
/**
 * @class Kohive.models.Application
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Application", {
			fields		: [{
						name	: 'id',
						type	: 'int'
					}, {
						name	: 'title',
						type	: 'string'
					}, {
						name	: 'id_default',
						type	: 'string'
					}, {
						name	: 'last_updated_at',
						type	: 'string'
					}, {
						name	: 'starred',
						type	: 'boolean'
					}, {
						name	: 'hidden',
						type	: 'boolean'
					}, {
						name	: 'enabled',
						type	: 'boolean'
					}, {
						name	: 'application_hives_id',
						type	: 'int'
					}, {
						name	: 'application_hive_memberships_id',
						type	: 'int'
					}],
			belongsTo	: "Membership"
		});

/**
 * @class Kohive.models.Hive
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Hive", {
	// adapter: 'kohive',
	fields	: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'url_slug',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'irc_channel_id',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'type',
				type	: 'string'
			}, {
				name	: 'title',
				type	: 'string'
			}, {
				name	: 'invite_hashcode',
				type	: 'string'
			}, {
				name	: 'short_description',
				type	: 'string'
			}, {
				name	: 'background_image',
				type	: 'string'
			}, {
				name	: 'top_toolbar_colour',
				type	: 'string'
			},

			{
				name	: 'level',
				type	: 'int'
			}, {
				name	: 'type',
				virtual	: true
			},

			{
				name	: 'creator_id',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'owner_id',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'creator_nickname',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'owner_nickname',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'creator_fullname',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'owner_fullname',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'member_count',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'personal_hive_id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'access_level',
				type	: 'string',
				virtual	: true
			}],
	hasMany	: ["Membership", "Milestone"]

		// saveWindowContext: function() {
		// var windows = [];
		// var manager = Kohive.OS.getWindowManager();
		//   
		// manager.each(function(win) {
		// windows.push(win);
		// win.close();
		// }, this);
		//   
		// return windows;
		// },
		// 
		// restoreWindowContext: function(windows) {
		// var windows = windows || [];
		//   
		// for (var i=0; i < windows.length; i++) {
		// windows[i].show();
		// };
		// }
	}
);

/**
 * @class Kohive.models.Membership
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Membership", {
			// adapter: 'kohive',
			fields				: [{
						name	: 'id',
						type	: 'int'
					}, {
						name	: 'id_card_id',
						type	: 'int'
					}, {
						name	: 'hive_id',
						type	: 'int'
					}, {
						name	: 'personal_hive_id',
						type	: 'int'
					}, {
						name	: 'access_level',
						type	: 'int'
					}, {
						name	: 'email',
						type	: 'string'
					}, {
						name	: 'state',
						type	: 'string'
					}, {
						name	: 'created_at',
						type	: 'string',
						virtual	: true
					}, {
						name	: 'updated_at',
						type	: 'string',
						virtual	: true
					},

					{
						name	: 'email_notifications',
						type	: 'string'
					}, {
						name	: 'email_subscriptions_string',
						type	: 'string'
					},

					{
						name	: 'starred',
						type	: 'bool',
						virtual	: true
					},

					{
						name	: 'hive',
						virtual	: true
					}, {
						name	: 'id_card',
						virtual	: true
					},

					{
						name	: 'photo_album',
						virtual	: true
					}, {
						name	: 'video_album',
						virtual	: true
					},

					{
						name	: 'sync_with_twitter',
						type	: 'bool'
					},

					{
						name	: 'zoho_auth_token',
						type	: 'string'
					},

					{
						name	: 'updated_at_date',
						virtual	: true,
						convert	: function(value, record) {
							return Kohive.OS.convertToDate(record.updated_at,
									true
							);
						}
					}, {
						name	: 'created_at_date',
						virtual	: true,
						convert	: function(value, record) {
							return Kohive.OS.convertToDate(record.created_at,
									true
							);
						}
					}],
			hasMany				: ["Hive", "Application", "Message"],

			// /**
			// * Creates the Url for membership
			// * @return {String} The Url
			// */
			// url: function() {
			// return '/memberships/' + this.data.id;
			// },

			/**
			 * Creates the Url for accepting a membership
			 * @return {String} The Url
			 */
			getAcceptUrl		: function() {
				return this.url() + '/accept';
			},

			/**
			 * Creates the Url for rejecting a membership
			 * @return {String} The Url
			 */
			getRejectUrl		: function() {
				return this.url() + '/reject';
			},

			/**
			 * Creates the Url for cancelling a membership
			 * @return {String} The Url
			 */
			getCancelUrl		: function() {
				return this.url() + '/cancel';
			},

			subscribedToEmail	: function(eventClass) {
				var returnValue = false;
				// Get only first eventClass in case it's a single option for multiple events
				eventClass = eventClass.split(',')[0];
				Ext.each(this.get("email_subscriptions_string").split(','),
						function(eventCls) {
							if (eventCls == eventClass) {
								return returnValue = true;
							}
						}
				);
				return returnValue || false;
			},

			subscribeToEmail	: function(eventClass) {
				var returnValue = false, email_subscriptions = this
						.get("email_subscriptions_string") == '' ? [] : this
						.get("email_subscriptions_string").split(',');

				email_subscriptions.push(eventClass);
				this.set("email_subscriptions_string", email_subscriptions
								.join(','));
				return returnValue || false;
			},

			unsubscribeToEmail	: function(eventClass) {
				var returnValue = false, email_subscriptions = [];
				Ext.each(this.get("email_subscriptions_string").split(','),
						function(eventCls) {
							if (eventCls != eventClass) {
								email_subscriptions.push(eventCls);
								returnValue = true;
							}
						}
				);
				this.set("email_subscriptions_string", email_subscriptions
								.join(','));
				return returnValue || false;
			}
		});

/**
 * @class Kohive.models.User
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.User", {
	// adapter: 'kohive',
	fields					: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			},
			// {name: 'alias', type: 'string'},
			// {name: 'language', type: 'string'},
			// {name: 'timezone', type: 'string'},
			{
				name	: 'email',
				type	: 'string'
			}, {
				name	: 'old_password',
				type	: 'string'
			}, {
				name	: 'password',
				type	: 'string'
			}, {
				name	: 'password_confirmation',
				type	: 'string'
			}, {
				name	: 'default_hive_id',
				type	: 'string'
			}, {
				name	: 'default_id_card_id',
				type	: 'string'
			}, {
				name	: 'level',
				type	: 'string'
			}, {
				name	: 'plan_switch_code',
				type	: 'string'
			}, {
				name	: 'shown_first_login',
				type	: 'bool'
			}, {
				name	: 'can_create_pro_hive',
				type	: 'bool',
				virtual	: true
			}, {
				name	: 'is_online',
				type	: 'bool',
				virtual	: true
			},

			{
				name	: 'language',
				type	: 'string',
				convert	: function(value, record) {
					if (!value)
						return "en-GB";
					else
						return value;
				}
			},

			{
				name	: 'renewal_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.renewal_date, true);
				}
			}],

	/**
	 * Stores the amount of pro hives the user currently has
	 */
	proHivesCount			: null,

	/**
	 * Counts the amount of pro hives the user has created
	 */
	countProHives			: function() {
		// get the hvies
		var hives = Kohive.OS.getCurrentMemberships();
		if (!hives)
			return;

		// loop through each of the hives and check if any has been created by them + is a pro hive
		hives.each(function(hive) {
					// console.log(hive.data.hive);
				}, this);
	},

	/**
	 * Checks if the user can create another pro hive
	 */
	canCreateProHive		: function() {
		return this.get('can_create_pro_hive');
	},

	/**
	 * 
	 */
	maxIdCards				: function() {
		return (this.get('plan_switch_code').split('-')[0] != "free") ? 100 : 2;
	},

	getResendSignupEmailUrl	: function() {
		return this.url() + '/resend_signup_email';
	}
}
);

/**
 * @class Kohive.models.Contact
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Contact", {
			modelName	: 'contact',
			jsonName	: 'contact',
			urlName		: 'contact',

			fields		: [{
						name	: 'service',
						type	: 'string'
					}, {
						name	: 'name',
						type	: 'string',
						virtual	: true
					}, {
						name	: 'login',
						type	: 'string'
					}, {
						name	: 'password',
						type	: 'string'
					}]
		});

/**
 * @class Kohive.models.ApplicationHiveMemberships
 * 
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.ApplicationHiveMembership", {
			modelName	: 'application_hive_membership',
			fields		: [{
						name	: 'id',
						type	: 'int',
						virtual	: true
					}, {
						name	: 'starred',
						type	: 'string'
					}]
		});

/**
 * @class Kohive.models.Session
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Session", {
			modelName	: 'session',
			fields		: [{
						name	: '_kohive_session',
						type	: 'string'
					}, {
						name	: 'auth_token',
						type	: 'string'
					}]
		});

ExtMVC.Model.define("Kohive.models.Message", {
	modelName	: 'message',
	// jsonName: 'message',
	// urlName: 'messages',

	fields		: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'assignee_membership_id',
				type	: 'int'
			}, {
				name	: 'hive_id',
				type	: 'int'
			}, {
				name	: 'body',
				type	: 'string'
			}, {
				name	: 'read',
				type	: 'bool'
			}, {
				name	: 'created_at',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			}, {
				name	: 'assignee_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.assignee_membership_id)
						return value;
					if (id == record.assignee_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					if (record.created_at)
						return Kohive.OS.convertToDate(record.created_at, true);
					else
						return false;
				}
			}]
}
);

/**
 * @class Kohive.models.Milestone
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Milestone", {
			fields		: [{
						name	: 'id',
						type	: 'int'
					}, {
						name	: 'hive_id',
						type	: 'int'
					}, {
						name	: 'title',
						type	: 'string'
					}, {
						name	: 'due_at',
						type	: 'string'
					}, {
						name	: 'created_at',
						type	: 'string',
						virtual	: true
					}, {
						name	: 'updated_at',
						type	: 'string',
						virtual	: true
					},

					{
						name	: 'due_at_date',
						virtual	: true,
						convert	: function(value, record) {
							return Kohive.OS.convertToDate(record.due_at, true);
						}
					}, {
						name	: 'updated_at_date',
						virtual	: true,
						convert	: function(value, record) {
							return Kohive.OS.convertToDate(record.updated_at,
									true
							);
						}
					}, {
						name	: 'created_at_date',
						virtual	: true,
						convert	: function(value, record) {
							return Kohive.OS.convertToDate(record.created_at,
									true
							);
						}
					}],
			belongsTo	: ["Membership"]
		}
);

ExtMVC.Model.define("Kohive.models.Update", {
			modelName	: 'update',

			fields		: [{
						name	: 'part',
						type	: 'string'
					}]
		});

/**
 * @class Kohive.models.Album
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Album", {
			fields	: [{
						name	: 'id',
						type	: 'int'
					}, {
						name	: 'author_membership_id',
						type	: 'int'
					}, {
						name	: 'title',
						type	: 'string'
					}, {
						name	: 'description',
						type	: 'string'
					}, {
						name	: 'hive_id',
						type	: 'int'
					}, {
						name	: 'type',
						type	: 'string'
					}, {
						name	: 'feed_url',
						type	: 'string'
					}, {
						name	: 'created_at',
						type	: 'string'
					}, {
						name	: 'updated_at',
						type	: 'string'
					},

					// editable properties
					{
						name	: 'can_edit',
						virtual	: true,
						convert	: function(value, record) {
							// return true always until proper checking can be done
							return true;

							// author
							// mod/owner
							if (Kohive.OS.isAuthor(record))
								return true;
							return false;
						}
					}, {
						name	: 'can_delete',
						virtual	: true,
						convert	: function(value, record) {
							// author
							// recipient
							// mod/owner
							if (Kohive.OS.isAuthor(record)
									|| Kohive.OS.isHiveMod())
								return true;
							return false;
						}
					}],
			hasMany	: "Image"
		});

/**
 * @class Kohive.models.BoardPost
 * @extends Ext.ux.MVC.Model
 */
ExtMVC.Model.define("Kohive.models.BoardPost", {
	modelName		: 'boardpost',
	jsonName		: 'boardpost',
	urlName			: 'board_posts',

	fields			: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'body',
				type	: 'string'
			}, {
				name	: 'body_html',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'recipient_membership_id',
				type	: 'int'
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'hive_id',
				type	: 'int'
			}, {
				name	: 'created_at',
				type	: 'string'
			},

			{
				name	: 'author_avatar',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'recipient_avatar',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			}, {
				name	: 'recipient_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.recipient_membership_id)
						return value;
					if (!record.recipient_membership_id)
						return Ext.ux.Translator.translate('everyone');
					if (id == record.recipient_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'toggled',
				type	: 'boolean',
				virtual	: true
			},

			// We need to use this in the template to check whether to show the reply button or not..
			{
				name	: 'user_membership_id',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.getCurrentHive().get('id');
				}
			},

			{
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at, true);
				}
			},

			{
				name	: 'tag_list',
				convert	: function(value, record) {
					if (!value && record.tags.length > 0) {
						var res = "";
						Ext.each(record.tags, function(tag) {
									res += tag.name + " ";
								}, this);
						return res;
					} else {
						return value;
					}
				}
			}, {
				name	: 'tags',
				virtual	: true,
				convert	: function(value, record) {
					if (value.length < 1)
						value = false;

					return value;
				}
			},

			// editable properties
			{
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// mod/owner
					if (Kohive.OS.isAuthor(record))
						return true;
					return false;
				}
			}, {
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// recipient
					// mod/owner
					if (Kohive.OS.isAuthor(record)
							|| Kohive.OS.isCustom(record,
									'recipient_membership_id', 'id'
							) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}],

	dataView		: new Ext.XTemplate(
			'<div class="x-pod-wrap">',
			'<tpl for=".">',
			'<div id="boardpost-{id}" class="x-pod x-boardpost<tpl if="can_edit"> x-editable-hover</tpl><tpl if="can_delete"> x-deletable-hover</tpl>">',
			'<div class="x-content-wrap">',
			'<div class="x-control-wrap"><div class="x-control"><div></div></div></div>',
			'<div class="x-content">',
			'<div class="x-title">',
			'<div class="x-title">{author_nickname}<tpl if="recipient_nickname"> <img class="x-spacer" src="/images/apps/right_arrow.png" /> {recipient_nickname}</tpl></div>',
			'<tpl if="toggled">',
			'<div class="x-toggle-extra">',
			'<tpl if="tags"><span class="x-tag"></span></tpl>',
			'<tpl if="user_membership_id != author_membership_id && hive_id != 47"><span class="x-reply-btn action-reply-reply"></span></tpl>',
			'</div>',
			'</tpl>',
			'<tpl if="!toggled">',
			'<div class="x-toggle-extra">',
			'<tpl if="user_membership_id != author_membership_id && hive_id != 47"><span class="x-reply-btn action-reply-reply"></span></tpl>',
			'</div>',
			'</tpl>',
			'</div>',
			'<tpl if="!toggled">',
			'<div class="x-extra">',
			'<div class="x-message<tpl if="recipient_avatar"> recipient</tpl>">',

			'<table cellpadding="0" width="100%">',
			'<tr>',
			'<td valign="top" nowrap="nowrap">',
			'<div class="x-avatar">',
			'<img src="{author_avatar}" />',
			'<tpl if="recipient_avatar">',
			'<img class="x-spacer" src="/images/apps/right_arrow_big.png" />',
			'<img src="{recipient_avatar}" />',
			'</tpl>',
			'</div>',
			'</td>',
			'<td valign="top" width="100%">',
			'<div class="action-edit-body">{body_html}</div>',
			'</td>',
			'</tr>',
			'</table>',

			'</div>',
			'<tpl if="tags">',
			'<div class="x-tags">',
			'<div class="action-editTags-tags">',
			'<div class="x-form-field-wrap x-trigger-field-wrap">',
			'<div class="x-form-text x-superboxselect  x-superboxselect-display-btns">',
			'<ul>',
			'<tpl for="tags">',
			'<li class="x-superboxselect-item no-close">{name}</li>',
			'</tpl>',
			'</ul>',
			'</div>',
			'</div>',
			'</div>',
			'</div>',
			'</tpl>',
			'<tpl if="!tags && can_edit">',
			'<div class="x-tags x-empty"><div class="action-editTags-tags">'
					+ Ext.ux.Translator.translate('app_add_tags')
					+ '</div></div>',
			'</tpl>',
			'<div class="x-other">',
			'<div class="x-created-on">' + '{created_at_date}</div>',
			'</div>',
			'</div>',
			'</tpl>',
			'</div>',
			'<div class="x-delete-wrap"><div class="x-delete"><div class="action-delete"></div></div></div>',
			'</div>', '</div>', '</tpl>', '</div>'
	),

	clickActions	: [{
		name			: 'body',
		value			: 'body',
		type			: 'edit',
		fieldType		: 'textarea',
		method			: 'dblclick',
		forceHeight		: true,
		forceRefresh	: true,
		emptyText		: Ext.ux.Translator
				.translate('app_boardposts_add_description')
	}, {
		name	: 'tags',
		type	: 'editTags',
		method	: 'dblclick'
	}, {
		name			: 'reply',
		type			: 'reply',
		method			: 'click',
		needsPermission	: false
	}],

	/**
	 * Method which attempts to reply to the records author
	 */
	reply			: function(dataview, record, el, a, index, indexWindow) {
		// Get the records author_membership_id
		var author_membership_id = record.get('author_membership_id');
		var tags = record.get('tags') || '';

		record.data.tag_list = "";
		Ext.each(tags, function(tag) {
					if (!tag.name)
						return;
					record.data.tag_list = record.get('tag_list') + ' '
							+ tag.name;
				}, this);

		// trim space at beginning, fixes bug that tag field stays empty
		record.data.tag_list = record.data.tag_list.trim();

		// Check if the newForm is there in the controller
		if (!indexWindow.newForm || !author_membership_id)
			return;

		// select the proper person in the combobox
		indexWindow.newForm.comboBox.setValue(author_membership_id);
		indexWindow.newForm.tagsField.setValue(record.get('tag_list'));
		if (indexWindow.newForm.collapsed)
			indexWindow.toggleNewForm(true);

		// Scroll to the top of the view
		Ext.get(indexWindow.el.select('.x-panel-body').elements[2].id).scroll(
				't', 30000, true
		);

		var tempTask = new Ext.util.DelayedTask(function() {
					// Focus on the body field
					Ext.get('board-posts-body' + Kohive.OS.getCurrentHiveId())
							.focus();
				}, this);
		tempTask.delay(1000);
	},

	/**
	 * 
	 */
	editTags		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-tags-field'
				});

		el.enableDisplayMode();
		el.hide();

		this.tagsField = new Ext.ux.form.SuperBoxSelect({
					renderTo		: 'edit-tags-field',
					allowAddNewData	: true,
					name			: 'tag_list',
					mode			: 'local',
					store			: indexWindow.tagsStore,
					displayField	: 'tag',
					valueField		: 'tag',
					listeners		: {
						scope		: this,
						newitem		: function(bs, v) {
							var newObj = {
								id		: v,
								name	: v,
								tag		: v
							};
							bs.addItem(newObj);
						},
						expand		: function() {
							var list = this.tagsField.list;

							var tempTask = new Ext.util.DelayedTask(function() {
										list.setTop(list.getTop() + 3);
									}, this);
							tempTask.delay(200);
						},
						'enter-key'	: function(field) {
							this.saveTags(field, record, sibling, el);
						},
						blur		: function(field) {
							this.saveTags(field, record, sibling, el);
						}
					}
				});

		this.tagsField.setWidth(sibling.getWidth());

		// format tags
		var tags = Ext.util.Format.trim(record.get('tag_list')).split(' ');

		var array = [];
		Ext.each(tags, function(t) {
					array.push({
								tag	: t
							});
				}, this);

		// set the tags value
		this.tagsField.setValueEx(array);

		this.tagsField.focus();
	},

	saveTags		: function(field, record, sibling, el, dataview) {
		var val = Ext.util.Format.trim(this.tagsField.getValue()).split(',');

		if (val.length > 0) {
			if (val.length == 1 && val[0] == "") {
				record.set('tag_list', '');
				record.set('tags', false);
				this.tagsField.setValue('');
			} else {
				var newArray = [];

				Ext.each(val, function(a) {
							newArray.push({
										name	: a
									});
						}, this);

				record.set('tag_list', val.join(' '));
				record.set('tags', false);
				record.set('tags', newArray);
				this.tagsField.setValue(val);
			};
		};

		this.showUpdating();

		record.save({
					url		: '/memberships/'
							+ Kohive.OS.getCurrentHive().get('id')
							+ '/board_posts/' + record.get('id'),
					scope	: this,
					success	: function() {
						this.tagsField.destroy();
						el.show();
						this.hideLoading();
					},
					failure	: Ext.emptyFn
				});
	},

	showUpdating	: function() {
		var controller = Kohive.OS.getController('boardposts');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.showUpdating();
	},

	/**
	 * Hides the loading animation from the view
	 */
	hideLoading		: function() {
		var controller = Kohive.OS.getController('boardposts');
		var view = controller.indexWindow || null;

		if (view) {
			view.hideLoading();
			view.fireEvent('update-filter-bar', view.cachedStore);
		};
	},

	/**
	 * Refreshes the content in the view
	 */
	refreshView		: function() {
		var controller = Kohive.OS.getController('boardposts');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.store.load();
		if (view)
			view.hideLoading();
	}
}
);

/**
 * @class Kohive.models.Blog
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Blog", {
	modelName		: 'blog',
	jsonName		: 'blog',
	urlName			: 'blog',

	fields			: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'hive_id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'title',
				type	: 'string'
			}, {
				name	: 'body',
				type	: 'string'
			}, {
				name	: 'body_html',
				type	: 'string'
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'created_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'modified_at',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'toggled',
				type	: 'boolean',
				virtual	: true
			},

			// comments
			{
				name	: 'toggled_comments',
				type	: 'boolean',
				virtual	: true
			}, {
				name	: 'comments',
				virtual	: true,
				convert	: function(value, record) {
					if (value)
						return value;
					else
						[];
				}
			}, {
				name	: 'new_comment',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'hide_comments',
				type	: 'boolean',
				virtual	: true
			},

			{
				name	: 'tag_list',
				convert	: function(value, record) {
					if (!value && record.tags.length > 0) {
						var res = "";
						Ext.each(record.tags, function(tag) {
									res += tag.name + " ";
								}, this);
						return res;
					} else {
						return value;
					}
				}
			}, {
				name	: 'tags',
				virtual	: true,
				convert	: function(value, record) {
					if (value.length < 1)
						value = false;

					return value;
				}
			},

			{
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at, true);
				}
			},

			// editable properties
			{
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// return true always until proper checking can be done
					return true;

					// author
					// mod/owner
					if (Kohive.OS.isAuthor(record))
						return true;
					return false;
				}
			}, {
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// recipient
					// mod/owner
					if (Kohive.OS.isAuthor(record) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}],

	dataView		: new Ext.XTemplate(
			'<div class="x-pod-wrap">',
			'<tpl for=".">',
			'<div id="blog-{id}" class="x-pod x-blog<tpl if="can_edit"> x-editable-hover</tpl><tpl if="can_delete"> x-deletable-hover</tpl>">',
			'<div class="x-content-wrap">',
			'<div class="x-control-wrap"><div class="x-control"><div></div></div></div>',
			'<div class="x-content">',
			'<div class="x-title">',
			'<div class="x-title action-edit-title">{title}</div>',
			'<tpl if="toggled">',
			'<div class="x-toggle-extra">',
			'<tpl if="tags"><span class="x-tag"></span></tpl>',
			'</div>',
			'</tpl>',
			'</div>',
			'<tpl if="!toggled">',
			'<div class="x-extra">',
			'<tpl if="body_html">',
			// '<div class="x-message"><div>{body_html}</div></div>',
			'<div class="x-message"><div class="action-edit-body">{body_html}</div></div>',
			'</tpl>',
			'<tpl if="tags">',
			'<div class="x-tags">',
			'<div class="action-editTags-tags">',
			'<div class="x-form-field-wrap x-trigger-field-wrap">',
			'<div class="x-form-text x-superboxselect  x-superboxselect-display-btns">',
			'<ul>',
			'<tpl for="tags">',
			'<li class="x-superboxselect-item no-close">{name}</li>',
			'</tpl>',
			'</ul>',
			'</div>',
			'</div>',
			'</div>',
			'</div>',
			'</tpl>',
			'<tpl if="!tags && can_edit">',
			'<div class="x-tags x-empty"><div class="action-editTags-tags">'
					+ Ext.ux.Translator.translate('app_add_tags')
					+ '</div></div>',
			'</tpl>',
			'<div class="x-other">',
			'<div class="x-created-on">'
					+ '{author_nickname}, {created_at_date}</div>',
			// '<div class="x-created-on">' + Ext.ux.Translator.translate('created_on') + ': {created_at_date}</div>',
			'</div>',
			'</div>',
			'</tpl>',
			'</div>',
			'<div class="x-delete-wrap"><div class="x-delete"><div class="action-delete"></div></div></div>',
			'</div>',

			'<tpl if="!toggled">',
			'<div class="x-comments<tpl if="this.isSmall(comments, toggled_comments, new_comment)"> x-small</tpl><tpl if="this.hasComments(comments)"> x-hascomments</tpl><tpl if="new_comment"> x-adding-comment</tpl>">',
			'<tpl if="!toggled_comments">',
			'<tpl for="comments">',
			'<div class="x-comment" id="blog-comment-{#}-{id}">',
			'<div class="x-delete-comment"><div></div></div>',
			'<div class="x-author"><img src="{thumb_filename}" /> {[Kohive.OS.isAuthor(values) ? Ext.ux.Translator.translate("me") : values.author_nickname]}</div>',
			'<div class="x-body">{content}</div>',
			'<div class="x-date">{[(values.created_at.split("T")[1]) ? Kohive.OS.convertToDate(values.created_at, true) : values.created_at]}</div>',
			'</div>',
			'</tpl>',
			'</tpl>',
			'<tpl if="!this.isSmall(comments, toggled_comments, new_comment)">',
			'<div class="x-new-comment<tpl if="this.hasComments(comments)"> x-extended</tpl><tpl if="new_comment"> x-is-field</tpl>">',
			'<tpl if="!new_comment && this.hasComments(comments)"><div class="x-toggle-button"><div class="x-img"></div></div></tpl>',
			'<tpl if="!new_comment"><div class="x-button"><div class="x-img"></div></div></tpl>',
			'<tpl if="new_comment">',
			'<div class="x-field"><input type="text" /></div>',
			'<div class="x-submit"><span>'
					+ Ext.ux.Translator.translate('post') + '</span></div>',
			'</tpl>',
			'</div>',
			'</tpl>',
			'<tpl if="this.isSmall(comments, toggled_comments, new_comment)">',
			'<div class="x-new-comment x-small">',
			'<tpl if="this.hasComments(comments)"><div class="x-toggle-button toggled"><div class="x-img"></div><span class="x-txt">{[this.commentsLength(values.comments)]}</span></div></tpl>',
			'<tpl if="!this.hasComments(comments)"><div class="x-button"><div class="x-img"></div><span class="x-txt">{[Ext.ux.Translator.translate("new_comment")]}</span></div></tpl>',
			'</div>', '</tpl>', '</div>', '</tpl>',

			{
				isSmall			: function(comments, toggled_comments,
						new_comment) {
					if (new_comment)
						return false;
					if (comments.length == 0 && toggled_comments)
						return true;
					if (comments.length == 0 && !toggled_comments)
						return true;
					if (comments.length > 0 && toggled_comments)
						return true;
					return false;
				},
				hasComments		: function(comments) {
					return comments.length > 0;
				},
				commentsLength	: function(comments) {
					var length = comments.length;
					if (comments.length == 0)
						return length + " "
								+ Ext.ux.Translator.translate('comments');
					if (comments.length == 1)
						return length + " "
								+ Ext.ux.Translator.translate('comment');
					if (comments.length > 1)
						return length + " "
								+ Ext.ux.Translator.translate('comments');
				}
			},

			'</div>', '</tpl>', '</div>'
	),

	clickActions	: [{
				name		: 'title',
				type		: 'edit',
				method		: 'dblclick',
				allowBlank	: false
			}, {
				name			: 'body',
				value			: 'body',
				type			: 'edit',
				fieldType		: 'textarea',
				forceRefresh	: true,
				method			: 'dblclick',
				forceHeight		: true
			}, {
				name	: 'tags',
				type	: 'editTags',
				method	: 'dblclick'
			}],

	/**
	 * 
	 */
	// updateBody: function(dataview, record, el, a, index) {
	// //create an element to store the tinymce instanse
	// var id = Ext.id(),
	// bodyEl = el.parent().createChild({
	// id: id,
	// cls: 'x-tinymce-ediable'
	// });
	//  
	// //hide the original el
	// el.enableDisplayMode();
	// el.hide();
	//  
	// //make the tinymce instance
	// tinyMCE.execCommand("mceAddControl", true, id);
	//  
	// //update content
	// var tempTask = new Ext.util.DelayedTask(function() {
	// var instance = tinyMCE.getInstanceById(id);
	// instance.setContent(record.get('body_html'));
	//    
	// //add a listener to the body
	// Ext.getBody().on('mousedown', function(e) {
	// var targetEl = Ext.get(e.getTarget());
	// 
	// var isBody = false;
	//        
	// //check if it is the body you click
	// if (targetEl.parent() && targetEl.parent().hasClass("mceToolbar")) isBody = true;
	// if (targetEl.parent() && targetEl.parent().hasClass("x-message")) isBody = true;
	// if (targetEl.parent().parent() && targetEl.parent().parent().hasClass("mceToolbar")) isBody = true;
	// if (targetEl.parent().parent() && targetEl.parent().parent().hasClass("x-message")) isBody = true;
	// if (targetEl.parent().parent().parent() && targetEl.parent().parent().parent().hasClass("mceToolbar")) isBody = true;
	// if (targetEl.parent().parent().parent() && targetEl.parent().parent().parent().hasClass("x-message")) isBody = true;
	// if (targetEl.parent().parent().parent().parent() && targetEl.parent().parent().parent().parent().hasClass("mceToolbar")) isBody = true;
	// if (targetEl.parent().parent().parent().parent() && targetEl.parent().parent().parent().parent().hasClass("x-message")) isBody = true;
	// if (targetEl.parent().parent().parent().parent().parent() && targetEl.parent().parent().parent().parent().parent().hasClass("mceToolbar")) isBody = true;
	// if (targetEl.parent().parent().parent().parent().parent() && targetEl.parent().parent().parent().parent().parent().hasClass("x-message")) isBody = true;
	// if (targetEl.parent().parent().parent().parent().parent() && targetEl.parent().parent().parent().parent().parent().parent().hasClass("mceToolbar")) isBody = true;
	// if (targetEl.parent().parent().parent().parent().parent() && targetEl.parent().parent().parent().parent().parent().parent().hasClass("x-message")) isBody = true;
	//      
	// if (!isBody) {
	// var content = instance.getContent();
	//        
	// this.showUpdating();
	//        
	// instance.remove();
	// bodyEl.remove();
	//        
	// //save and end
	// record.set('body_html', content);
	//        
	// // Update the record with the new state value
	// record.save({
	// url: '/memberships/' + Kohive.OS.getCurrentHive().get('id') + '/blog/' + record.get('id'),
	// success: this.refreshView,
	// failure: function() {
	// return Ext.Msg.alert('Error', 'Sorry, something went wrong. Please try again');
	// }
	// });
	// };
	// }, this);
	// }, this);
	// tempTask.delay(500);
	// },
	showUpdating	: function() {
		var controller = Kohive.OS.getController('blogs');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.showUpdating();
	},

	refreshView		: function() {
		var controller = Kohive.OS.getController('blogs');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.store.load();
		if (view && view.store)
			view.showRefreshing();
	},

	/**
	 * 
	 */
	editTags		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-tags-field'
				});

		el.enableDisplayMode();
		el.hide();

		this.tagsField = new Ext.ux.form.SuperBoxSelect({
					renderTo		: 'edit-tags-field',
					allowAddNewData	: true,
					name			: 'tag_list',
					mode			: 'local',
					store			: indexWindow.tagsStore,
					displayField	: 'tag',
					valueField		: 'tag',
					listeners		: {
						scope		: this,
						newitem		: function(bs, v) {
							var newObj = {
								id		: v,
								name	: v,
								tag		: v
							};
							bs.addItem(newObj);
						},
						expand		: function() {
							var list = this.tagsField.list;

							var tempTask = new Ext.util.DelayedTask(function() {
										list.setTop(list.getTop() + 3);
									}, this);
							tempTask.delay(200);
						},
						'enter-key'	: function(field) {
							this.saveTags(field, record, sibling, el);
						},
						blur		: function(field) {
							this.saveTags(field, record, sibling, el);
						}
					}
				});

		this.tagsField.setWidth(sibling.getWidth());

		// format tags
		var tags = Ext.util.Format.trim(record.get('tag_list')).split(' ');

		var array = [];
		Ext.each(tags, function(t) {
					array.push({
								tag	: t
							});
				}, this);

		// set the tags value
		this.tagsField.setValueEx(array);

		this.tagsField.focus();
	},

	saveTags		: function(field, record, sibling, el, dataview) {
		var val = Ext.util.Format.trim(this.tagsField.getValue()).split(',');

		if (val.length > 0) {
			if (val.length == 1 && val[0] == "") {
				record.set('tag_list', '');
				record.set('tags', false);
				this.tagsField.setValue('');
			} else {
				var newArray = [];

				Ext.each(val, function(a) {
							newArray.push({
										name	: a
									});
						}, this);

				record.set('tag_list', val.join(' '));
				record.set('tags', false);
				record.set('tags', newArray);
				this.tagsField.setValue(val);
			};
		};

		this.showUpdating();

		record.save({
					url		: '/memberships/'
							+ Kohive.OS.getCurrentHive().get('id') + '/blogs/'
							+ record.get('id'),
					scope	: this,
					success	: function() {
						this.tagsField.destroy();
						el.show();
						this.hideLoading();
					},
					failure	: Ext.emptyFn
				});
	},

	showUpdating	: function() {
		var controller = Kohive.OS.getController('blogs');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.showUpdating();
	},

	/**
	 * Hides the loading animation from the view
	 */
	hideLoading		: function() {
		var controller = Kohive.OS.getController('blogs');
		var view = controller.indexWindow || null;

		if (view) {
			view.hideLoading();
			view.fireEvent('update-filter-bar', view.cachedStore);
		};
	},

	/**
	 * Refreshes the content in the view
	 */
	refreshView		: function() {
		var controller = Kohive.OS.getController('blogs');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.store.load();
		if (view)
			view.hideLoading();
	}
}
);

/**
 * @class Kohive.models.Bookmark
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Bookmark", {
	modelName		: 'bookmark',
	fields			: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'hive_id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'title',
				type	: 'string'
			}, {
				name	: 'url',
				type	: 'string'
			}, {
				name	: 'note',
				type	: 'string'
			}, {
				name	: 'notes_html',
				type	: 'string'
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'created_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'modified_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'toggled',
				type	: 'boolean',
				virtual	: true
			},

			// comments
			{
				name	: 'toggled_comments',
				type	: 'boolean',
				virtual	: true
			}, {
				name	: 'comments',
				virtual	: true,
				convert	: function(value, record) {
					if (value)
						return value;
					else
						[];
				}
			}, {
				name	: 'new_comment',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'hide_comments',
				type	: 'boolean',
				virtual	: true
			},

			// convert fields
			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			}, {
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at, true);
				}
			},

			// tags
			{
				name	: 'tag_list',
				convert	: function(value, record) {
					if (!value && record.tags.length > 0) {
						var res = "";
						Ext.each(record.tags, function(tag) {
									res += tag.name + " ";
								}, this);
						return res;
					} else {
						return value;
					}
				}
			}, {
				name	: 'tags',
				virtual	: true,
				convert	: function(value, record) {
					if (value.length < 1)
						value = false;

					return value;
				}
			},

			// editable properties
			{
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// return true always until proper checking can be done
					return true;

					// author
					// mod/owner
					if (Kohive.OS.isAuthor(record))
						return true;
					return false;
				}
			}, {
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// recipient
					// mod/owner
					if (Kohive.OS.isAuthor(record) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}],

	dataView		: new Ext.XTemplate(
			'<div class="x-pod-wrap">',
			'<tpl for=".">',
			'<div id="bookmark-{id}" class="x-pod x-bookmark<tpl if="can_edit"> x-editable-hover</tpl><tpl if="can_delete"> x-deletable-hover</tpl>">',
			'<div class="x-content-wrap">',
			'<div class="x-control-wrap"><div class="x-control"><div></div></div></div>',
			'<div class="x-content">',
			'<div class="x-title">',
			'<div class="x-title action-edit-title">{title}</div>',
			'<tpl if="toggled">',
			'<div class="x-toggle-extra">',
			'<tpl if="tags"><span class="x-tag"></span></tpl>',
			'<tpl if="note"><span class="x-note"></span></tpl>',
			'<span class="x-url action-click-goto"></span>',
			'</div>',
			'</tpl>',
			'</div>',
			'<tpl if="!toggled">',
			'<div class="x-extra">',
			'<div class="x-url"><div class="x-go-btn action-click-goto"></div><div class="action-edit-url">{url}</div></div>',
			'<tpl if="note">',
			'<div class="x-description"><div class="action-edit-note">{notes_html}</div></div>',
			'</tpl>',
			'<tpl if="!note && can_edit">',
			'<div class="x-description x-empty"><div class="action-edit-note">'
					+ Ext.ux.Translator.translate('app_add_note')
					+ '</div></div>',
			'</tpl>',
			'<tpl if="tags">',
			'<div class="x-tags">',
			'<div class="action-editTags-tags">',
			'<div class="x-form-field-wrap x-trigger-field-wrap">',
			'<div class="x-form-text x-superboxselect  x-superboxselect-display-btns">',
			'<ul>',
			'<tpl for="tags">',
			'<li class="x-superboxselect-item no-close">{name}</li>',
			'</tpl>',
			'</ul>',
			'</div>',
			'</div>',
			'</div>',
			'</div>',
			'</tpl>',
			'<tpl if="!tags && can_edit">',
			'<div class="x-tags x-empty"><div class="action-editTags-tags">'
					+ Ext.ux.Translator.translate('app_add_tags')
					+ '</div></div>',
			'</tpl>',
			'<div class="x-other">',
			'<div class="x-created-on">'
					+ '{author_nickname}, {created_at_date}</div>',
			// '<div class="x-created-on">' + Ext.ux.Translator.translate('created_on') + ': {created_at_date}</div>',
			'</div>',
			'</div>',
			'</tpl>',
			'</div>',
			'<div class="x-delete-wrap"><div class="x-delete"><div class="action-delete"></div></div></div>',
			'</div>',

			'<tpl if="!toggled">',
			'<div class="x-comments<tpl if="this.isSmall(comments, toggled_comments, new_comment)"> x-small</tpl><tpl if="this.hasComments(comments)"> x-hascomments</tpl><tpl if="new_comment"> x-adding-comment</tpl>">',
			'<tpl if="!toggled_comments">',
			'<tpl for="comments">',
			'<div class="x-comment" id="bookmark-comment-{#}-{id}">',
			'<div class="x-delete-comment"><div></div></div>',
			'<div class="x-author"><img src="{thumb_filename}" /> {[Kohive.OS.isAuthor(values) ? Ext.ux.Translator.translate("me") : values.author_nickname]}</div>',
			'<div class="x-body">{content}</div>',
			'<div class="x-date">{[(values.created_at.split("T")[1]) ? Kohive.OS.convertToDate(values.created_at, true) : values.created_at]}</div>',
			'</div>',
			'</tpl>',
			'</tpl>',
			'<tpl if="!this.isSmall(comments, toggled_comments, new_comment)">',
			'<div class="x-new-comment<tpl if="this.hasComments(comments)"> x-extended</tpl><tpl if="new_comment"> x-is-field</tpl>">',
			'<tpl if="!new_comment && this.hasComments(comments)"><div class="x-toggle-button"><div class="x-img"></div></div></tpl>',
			'<tpl if="!new_comment"><div class="x-button"><div class="x-img"></div></div></tpl>',
			'<tpl if="new_comment">',
			'<div class="x-field"><input type="text" /></div>',
			'<div class="x-submit"><span>'
					+ Ext.ux.Translator.translate('post') + '</span></div>',
			'</tpl>',
			'</div>',
			'</tpl>',
			'<tpl if="this.isSmall(comments, toggled_comments, new_comment)">',
			'<div class="x-new-comment x-small">',
			'<tpl if="this.hasComments(comments)"><div class="x-toggle-button toggled"><div class="x-img"></div><span class="x-txt">{[this.commentsLength(values.comments)]}</span></div></tpl>',
			'<tpl if="!this.hasComments(comments)"><div class="x-button"><div class="x-img"></div><span class="x-txt">{[Ext.ux.Translator.translate("new_comment")]}</span></div></tpl>',
			'</div>', '</tpl>', '</div>', '</tpl>',

			{
				isSmall			: function(comments, toggled_comments,
						new_comment) {
					if (new_comment)
						return false;
					if (comments.length == 0 && toggled_comments)
						return true;
					if (comments.length == 0 && !toggled_comments)
						return true;
					if (comments.length > 0 && toggled_comments)
						return true;
					return false;
				},
				hasComments		: function(comments) {
					return comments.length > 0;
				},
				commentsLength	: function(comments) {
					var length = comments.length;
					if (comments.length == 0)
						return length + " "
								+ Ext.ux.Translator.translate('comments');
					if (comments.length == 1)
						return length + " "
								+ Ext.ux.Translator.translate('comment');
					if (comments.length > 1)
						return length + " "
								+ Ext.ux.Translator.translate('comments');
				}
			},

			'</div>', '</tpl>', '</div>'
	),

	clickActions	: [{
				name		: 'title',
				type		: 'edit',
				method		: 'dblclick',
				allowBlank	: false
			}, {
				name		: 'url',
				type		: 'edit',
				method		: 'dblclick',
				allowBlank	: false
			}, {
				name			: 'note',
				value			: 'note',
				type			: 'edit',
				fieldType		: 'textarea',
				method			: 'dblclick',
				emptyText		: Ext.ux.Translator.translate('app_add_note'),
				forceRefresh	: true
			}, {
				name	: 'tags',
				type	: 'editTags',
				method	: 'dblclick'
			}, {
				name		: 'goto',
				fieldName	: 'url',
				type		: 'click',
				method		: 'click'
			}],

	/**
	 * 
	 */
	editTags		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-tags-field'
				});

		el.enableDisplayMode();
		el.hide();

		this.tagsField = new Ext.ux.form.SuperBoxSelect({
					renderTo		: 'edit-tags-field',
					allowAddNewData	: true,
					name			: 'tag_list',
					mode			: 'local',
					store			: indexWindow.tagsStore,
					displayField	: 'tag',
					valueField		: 'tag',
					listeners		: {
						scope		: this,
						newitem		: function(bs, v) {
							var newObj = {
								id		: v,
								name	: v,
								tag		: v
							};
							bs.addItem(newObj);
						},
						expand		: function() {
							var list = this.tagsField.list;

							var tempTask = new Ext.util.DelayedTask(function() {
										list.setTop(list.getTop() + 3);
									}, this);
							tempTask.delay(200);
						},
						'enter-key'	: function(field) {
							this.saveTags(field, record, sibling, el);
						},
						blur		: function(field) {
							this.saveTags(field, record, sibling, el);
						}
					}
				});

		this.tagsField.setWidth(sibling.getWidth());

		// format tags
		var tags = Ext.util.Format.trim(record.get('tag_list')).split(' ');

		var array = [];
		Ext.each(tags, function(t) {
					array.push({
								tag	: t
							});
				}, this);

		// set the tags value
		this.tagsField.setValueEx(array);

		this.tagsField.focus();
	},

	saveTags		: function(field, record, sibling, el, dataview) {
		var val = Ext.util.Format.trim(this.tagsField.getValue()).split(',');

		if (val.length > 0) {
			if (val.length == 1 && val[0] == "") {
				record.set('tag_list', '');
				record.set('tags', false);
				this.tagsField.setValue('');
			} else {
				var newArray = [];

				Ext.each(val, function(a) {
							newArray.push({
										name	: a
									});
						}, this);

				record.set('tag_list', val.join(' '));
				record.set('tags', false);
				record.set('tags', newArray);
				this.tagsField.setValue(val);
			};
		};

		this.showUpdating();

		record.save({
					url		: '/memberships/'
							+ Kohive.OS.getCurrentHive().get('id')
							+ '/bookmarks/' + record.get('id'),
					scope	: this,
					success	: function() {
						this.tagsField.destroy();
						el.show();
						this.hideLoading();
					},
					failure	: Ext.emptyFn
				});
	},

	showUpdating	: function() {
		var controller = Kohive.OS.getController('bookmarks');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.showUpdating();
	},

	/**
	 * Hides the loading animation from the view
	 */
	hideLoading		: function() {
		var controller = Kohive.OS.getController('bookmarks');
		var view = controller.indexWindow || null;

		if (view) {
			view.hideLoading();
			view.fireEvent('update-filter-bar', view.cachedStore);
		};
	},

	/**
	 * Refreshes the content in the view
	 */
	refreshView		: function() {
		var controller = Kohive.OS.getController('bookmarks');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.store.load();
		if (view)
			view.hideLoading();
	}
}
);

/**
 * @class Kohive.models.Comment
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Comment", {
			fields		: [{
						name	: 'id',
						type	: 'int'
					}, {
						name	: 'other_id',
						type	: 'int',
						virtual	: true
					}, {
						name	: 'title',
						type	: 'string'
					}, {
						name	: 'content',
						type	: 'string'
					}, {
						name	: 'author_membership_id',
						type	: 'int'
					}, {
						name	: 'thumb_filename',
						type	: 'string',
						virtual	: true
					}, {
						name	: 'created_at',
						type	: 'string',
						virtual	: true
					}, {
						name	: 'updated_at',
						type	: 'string'
					},

					{
						name	: 'author_nickname',
						type	: 'string',
						virtual	: true,
						convert	: function(value, record) {
							var id = Kohive.OS.getCurrentHive().get('id');

							if (!id || !record.author_membership_id)
								return value;
							if (id == record.author_membership_id)
								return Ext.ux.Translator.translate('me');
							return value;
						}
					},

					{
						name	: 'created_at_date',
						virtual	: true,
						convert	: function(value, record) {
							return Kohive.OS.convertToDate(record.created_at,
									true
							);
						}
					},

					{
						name	: 'can_edit',
						virtual	: true,
						convert	: function(value, record) {
							if (Kohive.OS.isAuthor(record))
								return true;
							return false;
						}
					}, {
						name	: 'can_delete',
						virtual	: true,
						convert	: function(value, record) {
							// author
							// recipient
							// mod/owner
							if (Kohive.OS.isAuthor(record)
									|| Kohive.OS.isHiveMod())
								return true;
							return false;
						}
					}],
			belongsTo	: ["Image", "Video", "Task"]
		});

/**
 * @class Kohive.models.DesktopSticky
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.DesktopSticky", {
	modelName	: 'desktop_sticky',
	fields		: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'hive_id',
				type	: 'int'
			}, {
				name	: 'sticky_id',
				type	: 'int'
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'created_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'updated_at',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'the_sticky',
				virtual	: true
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.the_sticky.author_membership_id)
						return record.the_sticky.author_nickname;
					if (id == record.the_sticky.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return record.the_sticky.author_nickname;
				}
			},

			{
				name	: 'color_cls',
				virtual	: true,
				convert	: function(value, record) {
					return record.the_sticky.color
							+ (Math.floor(Math.random() * 3) + 1);
				}
			}, {
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(
							record.the_sticky.created_at, true
					);
				}
			},

			// editable properties
			{
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// mod/owner
					if (Kohive.OS.isAuthor(record) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}],

	dataView	: new Ext.XTemplate(
			'<div class="x-pod-wrap">',
			'<tpl for=".">',
			'<div id="desktop-sticky-{id}" class="x-sticky {values.the_sticky.color} {color_cls} x-pod<tpl if="can_delete"> x-deletable-hover</tpl>">',
			'<div class="x-stamp<tpl if="values.the_sticky.stamp"> {values.the_sticky.stamp}</tpl>">',
			'<div class="x-created">{author_nickname}, {created_at_date}</div>',
			'<div class="x-delete-wrap"><div class="x-delete"><div class="action-delete"></div></div></div>',
			'</div>',
			'<div id="middle" class="x-sticky-wrap">',
			'<div id="inner" class="x-sticky-inner-wrap">',
			'<div class="x-body action-edit-body">{values.the_sticky.body_html}</div>',
			'</div>', '</div>', '</div>', '</tpl>', '</div>'
	)
}
);

/**
 * @class Kohive.models.File
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.File", {
	modelName		: 'file',
	urlName			: 'file',
	jsonName		: 'file',
	fields			: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'title',
				type	: 'string'
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'file_file_name',
				type	: 'string'
			}, {
				name	: 'file_file_size',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'url',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'extension',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'file_extension',
				type	: 'string'
			}, {
				name	: 'description',
				type	: 'string'
			}, {
				name	: 'description_html',
				type	: 'string'
			},

			{
				name	: 'versions',
				virtual	: true,
				convert	: function(value, record) {
					var array = [], value = value || [], i = 1;

					Ext.each(value, function(version, index) {
						if (index == value.length - 1)
							return;

						// date
						version.created_at = Kohive.OS.convertToDate(
								version.created_at, true
						);

						// file size
						var file_file_size = version.file_file_size, newValue = 0, type = "mb";
						newValue = Math.round(file_file_size / 1048576 * 100)
								/ 100;
						if (/^0.*/.test(newValue)) {
							newValue = Math.round(file_file_size / 1024);
							type = "kb";
						};
						version.file_file_size = newValue + " " + type;

						// version id
						version.num = i;
						i = i + 1;

						array.push(version);
					}, this
					);

					return (array.length > 0) ? array.reverse() : false;
				}
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'toggled',
				type	: 'boolean',
				virtual	: true
			},

			{
				name	: 'tag_list',
				convert	: function(value, record) {
					if (!value && record.tags.length > 0) {
						var res = "";
						Ext.each(record.tags, function(tag) {
									res += tag.name + " ";
								}, this);
						return res;
					} else {
						return value;
					}
				}
			}, {
				name	: 'tags',
				virtual	: true,
				convert	: function(value, record) {
					if (value.length < 1)
						value = false;

					return value;
				}
			},

			{
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at);
				}
			}, {
				name	: 'id_card',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS
							.getIdCardFromMembershipId(record.author_membership_id);
				}
			},

			// editable properties
			{
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// return true always until proper checking can be done
					return true;

					// author
					// mod/owner
					if (Kohive.OS.isAuthor(record))
						return true;
					return false;
				}
			}, {
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// recipient
					// mod/owner
					if (Kohive.OS.isAuthor(record) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}],

	clickActions	: [{
				name		: 'title',
				type		: 'edit',
				method		: 'dblclick',
				allowBlank	: false
			},
			// {
			// name: 'url',
			// type: 'edit',
			// method: 'dblclick',
			// allowBlank: false
			// },
			{
				name			: 'description',
				value			: 'description',
				type			: 'edit',
				fieldType		: 'textarea',
				method			: 'dblclick',
				emptyText		: Ext.ux.Translator
						.translate('app_add_description'),
				forceRefresh	: true
			}, {
				name			: 'tags',
				type			: 'editTags',
				method			: 'dblclick',
				forceRefresh	: true
			}],

	// belongsTo: "Album",
	hasMany			: "Comment",

	/**
	 * 
	 */
	editTags		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-tags-field'
				});

		el.enableDisplayMode();
		el.hide();

		this.tagsField = new Ext.ux.form.SuperBoxSelect({
					renderTo		: 'edit-tags-field',
					allowAddNewData	: true,
					name			: 'tag_list',
					mode			: 'local',
					store			: indexWindow.tagsStore,
					displayField	: 'tag',
					valueField		: 'tag',
					listeners		: {
						scope		: this,
						newitem		: function(bs, v) {
							var newObj = {
								id		: v,
								name	: v,
								tag		: v
							};
							bs.addItem(newObj);
						},
						expand		: function() {
							var list = this.tagsField.list;

							var tempTask = new Ext.util.DelayedTask(function() {
										list.setTop(list.getTop() + 3);
									}, this);
							tempTask.delay(200);
						},
						'enter-key'	: function(field) {
							this.saveTags(field, record, sibling, el);
						},
						blur		: function(field) {
							this.saveTags(field, record, sibling, el);
						}
					}
				});

		this.tagsField.setWidth(sibling.getWidth());

		// format tags
		var tags = Ext.util.Format.trim(record.get('tag_list')).split(' ');

		var array = [];
		Ext.each(tags, function(t) {
					array.push({
								tag	: t
							});
				}, this);

		// set the tags value
		this.tagsField.setValueEx(array);

		this.tagsField.focus();
	},

	saveTags		: function(field, record, sibling, el, dataview) {
		var val = Ext.util.Format.trim(this.tagsField.getValue()).split(',');

		if (val.length > 0) {
			if (val.length == 1 && val[0] == "") {
				record.set('tag_list', '');
				record.set('tags', false);
				this.tagsField.setValue('');
			} else {
				var newArray = [];

				Ext.each(val, function(a) {
							newArray.push({
										name	: a
									});
						}, this);

				record.set('tag_list', val.join(' '));
				record.set('tags', false);
				record.set('tags', newArray);
				this.tagsField.setValue(val);
			};
		};

		this.showUpdating();

		record.save({
					url		: '/memberships/'
							+ Kohive.OS.getCurrentHive().get('id')
							+ '/file_cabinets/' + record.get('id'),
					scope	: this,
					success	: function() {
						this.tagsField.destroy();
						el.show();
						this.hideLoading();
						this.refreshView();
					},
					failure	: Ext.emptyFn
				});
	},

	showUpdating	: function() {
		var controller = Kohive.OS.getController('filecabinet');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.showUpdating();
	},

	/**
	 * Hides the loading animation from the view
	 */
	hideLoading		: function() {
		var controller = Kohive.OS.getController('filecabinet');
		var view = controller.indexWindow || null;

		if (view) {
			view.hideLoading();
			view.fireEvent('update-filter-bar', view.cachedStore);
		};
	},

	/**
	 * Refreshes the content in the view
	 */
	refreshView		: function() {
		var controller = Kohive.OS.getController('filecabinet');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.store.load();
		if (view)
			view.hideLoading();
	}
}
);

/**
 * @class Kohive.models.IdCard
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.IdCard", {
	modelName		: 'id_card',
	fields			: [{
				name	: 'id',
				type	: 'int'
			}, {
				name	: 'user_id',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'name',
				type	: 'string'
			}, {
				name	: 'is_default?',
				type	: 'bool',
				virtual	: true
			},

			{
				name	: 'large_filename',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'medium_filename',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'thumb_filename',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'circle_filename',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'hexagon_filename',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'full_name',
				type	: 'string'
			}, {
				name	: 'nickname',
				type	: 'string'
			},

			{
				name	: 'website',
				type	: 'string'
			}, {
				name	: 'email',
				type	: 'string'
			}, {
				name	: 'phone',
				type	: 'string'
			},

			{
				name	: 'job_title',
				type	: 'string'
			}, {
				name	: 'sexuality',
				type	: 'string'
			}, {
				name	: 'location',
				type	: 'string'
			}, {
				name	: 'relationship',
				type	: 'string'
			}, {
				name	: 'gender',
				type	: 'string'
			}, {
				name	: 'birthday',
				type	: 'string'
			}, {
				name	: 'religion',
				type	: 'string'
			}, {
				name	: 'political_view',
				type	: 'string'
			}, {
				name	: 'heritage',
				type	: 'string'
			}, {
				name	: 'diet',
				type	: 'string'
			},

			{
				name	: 'activites',
				type	: 'string'
			}, {
				name	: 'topics',
				type	: 'string'
			}, {
				name	: 'foods',
				type	: 'string'
			}, {
				name	: 'drinks',
				type	: 'string'
			}, {
				name	: 'movies',
				type	: 'string'
			}, {
				name	: 'tv_shows',
				type	: 'string'
			}, {
				name	: 'music',
				type	: 'string'
			}, {
				name	: 'books',
				type	: 'string'
			}, {
				name	: 'role_models',
				type	: 'string'
			}, {
				name	: 'places',
				type	: 'string'
			}, {
				name	: 'quotes',
				type	: 'string'
			},

			{
				name	: 'skype',
				type	: 'string'
			}, {
				name	: 'linked_in',
				type	: 'string'
			}, {
				name	: 'twitter',
				type	: 'string'
			}, {
				name	: 'im',
				type	: 'string'
			}, {
				name	: 'blog',
				type	: 'string'
			}, {
				name	: 'other',
				type	: 'string'
			},

			{
				name	: 'bio',
				type	: 'string'
			}, {
				name	: 'bio_html',
				type	: 'string'
			},

			{
				name	: 'verified_email',
				type	: 'boolean'
			},

			{
				name	: 'user',
				virtual	: true
			},

			{
				name	: 'last_notified_event_id',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'created_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'modified_at',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'birthday_date',
				virtual	: true,
				convert	: function(value, record) {
					if (!record.birthday)
						return "";
					return Kohive.OS.convertToDate(record.birthday, true); // TODO change to j-M-y when chronic can support it);
				}
			},

			{
				name	: 'birthday_normal',
				virtual	: true,
				convert	: function(value, record) {
					if (!record.birthday)
						return "";
					return Kohive.OS.convertToDate(record.birthday, false); // TODO change to j-M-y when chronic can support it);
				}
			},

			{
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// Check if the current users id is equal to the id cards user id
					var currentUserId = Kohive.OS.getCurrentUser().data.id;
					var idCardUserId = record.user_id;

					if (currentUserId == idCardUserId)
						return true;

					return false;
				}
			}],

	/**
	 * @property clickActions
	 * @type Array
	 * An array of click actions for the id card
	 */
	clickActions	: (function() {
		// Loop through all fields except virtual and
		var array = [], fields = ['name', 'full_name', 'nickname', 'website',
				'email', 'phone', 'job_title', 'sexuality', 'location',
				'relationship', 'birthday', 'religion', 'political_view',
				'heritage', 'gender', 'activites', 'topics', 'foods', 'diet',
				'drinks', 'movies', 'tv_shows', 'music', 'books',
				'role_models', 'places', 'quotes', 'bio', 'avatar',

				// extra added 27/11/09
				'skype', 'linked_in', 'twitter', 'im', 'blog', 'other'];

		var defaults = {
			type	: 'edit',
			method	: 'dblclick'
		};

		// Loop through all the fields (above) and create the clickActions for the model from them
		Ext.each(fields, function(field) {
			if (field == "avatar")
				return;

			var obj = Ext.applyIf({
						name	: field,
						value	: field
					}, defaults);

			if (field == "bio") {
				obj.fieldType = 'textarea';
				obj.value = "bio";
				obj.forceHeight = true;
				obj.forceRefresh = true;
			};
			if (field == "name" || field == "full_name" || field == "nickname") {
				obj.allowBlank = false;
			};

			if (field == "birthday") {
				obj.value = "birthday_date";
				obj.forceRefresh = true;
				obj.type = "datePicker";
			};
			if (field == "gender") {
				obj.type = "genderPicker";
			};

			if (field == "email") {
				obj.vtype = "email";
			};
			if (field == "website") {
				obj.vtype = "urlWithoutHttp";
			};

			array.push(obj);
		}, this
		);

		return array;
	})(),

	/**
	 * Creates a new datefield
	 */
	datePicker		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id			: 'edit-birthday-field',
					cls			: 'edit-birthday-field',
					children	: [{
								id			: 'edit-birthday-day',
								tag			: 'select',
								children	: [{
											tag		: 'option',
											html	: '1'
										}, {
											tag		: 'option',
											html	: '2'
										}, {
											tag		: 'option',
											html	: '3'
										}, {
											tag		: 'option',
											html	: '4'
										}, {
											tag		: 'option',
											html	: '5'
										}, {
											tag		: 'option',
											html	: '6'
										}, {
											tag		: 'option',
											html	: '7'
										}, {
											tag		: 'option',
											html	: '8'
										}, {
											tag		: 'option',
											html	: '9'
										}, {
											tag		: 'option',
											html	: '10'
										}, {
											tag		: 'option',
											html	: '11'
										}, {
											tag		: 'option',
											html	: '12'
										}, {
											tag		: 'option',
											html	: '13'
										}, {
											tag		: 'option',
											html	: '14'
										}, {
											tag		: 'option',
											html	: '15'
										}, {
											tag		: 'option',
											html	: '16'
										}, {
											tag		: 'option',
											html	: '17'
										}, {
											tag		: 'option',
											html	: '18'
										}, {
											tag		: 'option',
											html	: '19'
										}, {
											tag		: 'option',
											html	: '20'
										}, {
											tag		: 'option',
											html	: '21'
										}, {
											tag		: 'option',
											html	: '22'
										}, {
											tag		: 'option',
											html	: '23'
										}, {
											tag		: 'option',
											html	: '24'
										}, {
											tag		: 'option',
											html	: '25'
										}, {
											tag		: 'option',
											html	: '26'
										}, {
											tag		: 'option',
											html	: '27'
										}, {
											tag		: 'option',
											html	: '28'
										}, {
											tag		: 'option',
											html	: '29'
										}, {
											tag		: 'option',
											html	: '30'
										}, {
											tag		: 'option',
											html	: '31'
										}]
							}, {
								id			: 'edit-birthday-month',
								tag			: 'select',
								children	: [{
											tag		: 'option',
											value	: '1',
											html	: 'Jan'
										}, {
											tag		: 'option',
											value	: '2',
											html	: 'Feb'
										}, {
											tag		: 'option',
											value	: '3',
											html	: 'Mar'
										}, {
											tag		: 'option',
											value	: '4',
											html	: 'Apr'
										}, {
											tag		: 'option',
											value	: '5',
											html	: 'May'
										}, {
											tag		: 'option',
											value	: '6',
											html	: 'Jun'
										}, {
											tag		: 'option',
											value	: '7',
											html	: 'Jul'
										}, {
											tag		: 'option',
											value	: '8',
											html	: 'Aug'
										}, {
											tag		: 'option',
											value	: '9',
											html	: 'Sep'
										}, {
											tag		: 'option',
											value	: '10',
											html	: 'Oct'
										}, {
											tag		: 'option',
											value	: '11',
											html	: 'Nov'
										}, {
											tag		: 'option',
											value	: '12',
											html	: 'Dec'
										}]
							}, {
								id		: 'edit-birthday-year',
								tag		: 'input',
								type	: 'text',
								value	: '1981',
								vtype	: 'bdayyear'
							}]
				});

		el.enableDisplayMode();
		el.hide();

		var scope = this;

		var onSubmit = function() {
			var day = Ext.get('edit-birthday-day').dom.value, month = Ext
					.get('edit-birthday-month').dom.value, year = Ext
					.get('edit-birthday-year').dom.value;

			var date = new Date(year, month - 1, day);

			if (date) {
				record.set('birthday', date.format('d M y')); // TODO change to j-M-y when chronic can support it
				record.set('birthday_date', date.format('d-M-y')); // TODO change to j-M-y when chronic can support it
			} else {
				record.set('birthday', '');
				record.set('birthday_date', '');
			};

			record.save({
						url		: '/memberships/'
								+ Kohive.OS.getCurrentHive().get('id')
								+ '/id_cards/' + record.get('id'),
						scope	: this,
						success	: function() {
							sibling.remove();
							el.show();
						},
						failure	: function() {

						}
					});
		};

		var onClick = function() {
			if (scope.emailTimer)
				clearTimeout(scope.emailTimer);
			scope.emailTimer = setTimeout(onSubmit, 1000);
		};

		Ext.getBody().on('mousedown', function(e) {
			var el = Ext.get(e.getTarget());

			if (el.hasClass('edit-birthday-field')
					|| el.parent().hasClass('edit-birthday-field')
					|| el.parent().parent().hasClass('edit-birthday-field')
					|| el.parent().parent().parent()
							.hasClass('edit-birthday-field')) {
				clearTimeout(scope.emailTimer);
			} else {
				onClick();
			};
		}, this
		);

		// var dateField = new Ext.form.DateField({
		// renderTo: 'edit-birthday-field',
		// name: 'birthday',
		// value: (record.get('birthday_normal')) ? record.get('birthday_normal') : '',
		// showToday: false,
		// width: 110,
		// format: 'd-M-y', // TODO change to j-M-y when chronic can support it
		// listeners: {
		// scope : this,
		// 'focus' : function(field) {
		// field.onTriggerClick();
		// },
		// 'blur' : function(field) {
		// var date = field.getValue();
		//      
		// if (date) {
		// record.set('birthday', date.format('d M y')); // TODO change to j-M-y when chronic can support it
		// record.set('birthday_date', date.format('d-M-y')); // TODO change to j-M-y when chronic can support it
		// } else {
		// record.set('birthday', '');
		// record.set('birthday_date', '');
		// };
		//      
		// record.save({
		// url: '/memberships/' + Kohive.OS.getCurrentHive().get('id') + '/id_cards/' + record.get('id'),
		// scope: this,
		// success: function() {
		// sibling.remove();
		// el.show();
		// },
		// failure: function() {
		//          
		// }
		// });
		// }
		// }
		// });
	},

	/**
	 * Creates a new combobox for gender
	 */
	genderPicker	: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-gender-field',
					cls	: 'edit-birthday-field'
				});

		el.enableDisplayMode();
		el.hide();

		var dateField = new Ext.form.ComboBox({
					renderTo		: 'edit-gender-field',
					name			: 'gender',
					value			: record.get('gender'),
					width			: 110,
					store			: new Ext.data.SimpleStore({
								fields	: ['gender', 'label'],
								data	: [
										[
												'male',
												Ext.ux.Translator
														.translate('male')],
										[
												'female',
												Ext.ux.Translator
														.translate('female')]]
							}),
					selectOnFocus	: true,
					triggerAction	: 'all',
					displayField	: 'label',
					typeAhead		: true,
					emptyText		: '',
					mode			: 'local',
					listeners		: {
						scope	: this,
						'blur'	: function(field) {
							var gender = field.getValue();
							if (!gender) {
								sibling.remove();
								el.show();

								return;
							};

							record.set('gender', gender);
							record.save({
										url		: '/memberships/'
												+ Kohive.OS.getCurrentHive()
														.get('id')
												+ '/id_cards/'
												+ record.get('id'),
										scope	: this,
										success	: function() {
											sibling.remove();
											el.show();
										},
										failure	: function() {

										}
									});
						}
					}
				});

		var tempTask = new Ext.util.DelayedTask(function() {
					dateField.focus();
				}, this);
		tempTask.delay(100);
	}
}
);

/**
 * @class Kohive.models.Image
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Image", {
	fields			: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'album_id',
				type	: 'int'
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'size',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'content_type',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'file_url',
				type	: 'string'
			}, {
				name	: 'filename',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'height',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'width',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'parent_id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'thumbnail',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'title',
				type	: 'string'
			}, {
				name	: 'description',
				type	: 'string'
			}, {
				name	: 'description_html',
				type	: 'string'
			}, {
				name	: 'taken_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'created_at',
				type	: 'string'
			}, {
				name	: 'updated_at',
				type	: 'string'
			}, {
				name	: 'thumb_filename',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'medium_filename',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'original_filename',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'is_remote_image',
				type	: 'bool',
				virtual	: true
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'tag_list',
				convert	: function(value, record) {
					if (!value && record.tags.length > 0) {
						var res = "";
						Ext.each(record.tags, function(tag) {
									res += tag.name + " ";
								}, this);
						return res;
					} else {
						return value;
					}
				}
			}, {
				name	: 'tags',
				virtual	: true,
				convert	: function(value, record) {
					if (value.length < 1)
						value = false;

					return value;
				}
			},

			{
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at, true);
				}
			}, {
				name	: 'id_card',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS
							.getIdCardFromMembershipId(record.author_membership_id);
				}
			},

			// editable properties
			{
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// return true always until proper checking can be done
					return true;

					// author
					// mod/owner
					if (Kohive.OS.isAuthor(record))
						return true;
					return false;
				}
			}, {
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// recipient
					// mod/owner
					if (Kohive.OS.isAuthor(record) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}],

	belongsTo		: "Album",
	hasMany			: "Comment",

	/**
	 * 
	 */
	editTags		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-tags-field'
				});

		el.enableDisplayMode();
		el.hide();

		this.tagsField = new Ext.ux.form.SuperBoxSelect({
					renderTo		: 'edit-tags-field',
					allowAddNewData	: true,
					name			: 'tag_list',
					mode			: 'local',
					store			: indexWindow.tagsStore,
					displayField	: 'tag',
					valueField		: 'tag',
					listeners		: {
						scope		: this,
						newitem		: function(bs, v) {
							var newObj = {
								id		: v,
								name	: v,
								tag		: v
							};
							bs.addItem(newObj);
						},
						expand		: function() {
							var list = this.tagsField.list;

							var tempTask = new Ext.util.DelayedTask(function() {
										list.setTop(list.getTop() + 3);
									}, this);
							tempTask.delay(200);
						},
						'enter-key'	: function(field) {
							this.saveTags(field, record, sibling, el);
						},
						blur		: function(field) {
							this.saveTags(field, record, sibling, el);
						}
					}
				});

		this.tagsField.setWidth(sibling.getWidth());

		// format tags
		var tags = Ext.util.Format.trim(record.get('tag_list')).split(' ');

		var array = [];
		Ext.each(tags, function(t) {
					array.push({
								tag	: t
							});
				}, this);

		// set the tags value
		this.tagsField.setValueEx(array);

		this.tagsField.focus();
	},

	saveTags		: function(field, record, sibling, el, dataview) {
		var val = Ext.util.Format.trim(this.tagsField.getValue()).split(',');

		if (val.length > 0) {
			if (val.length == 1 && val[0] == "") {
				record.set('tag_list', '');
				record.set('tags', false);
				this.tagsField.setValue('');
			} else {
				var newArray = [];

				Ext.each(val, function(a) {
							newArray.push({
										name	: a
									});
						}, this);

				record.set('tag_list', val.join(' '));
				record.set('tags', false);
				record.set('tags', newArray);
				this.tagsField.setValue(val);
			};
		};

		this.showUpdating();

		record.save({
					url		: Kohive.OS.scopedUrl(String.format(
							"albums/{0}/images/{1}", record.get('album_id'),
							record.get('id')
					)),
					scope	: this,
					success	: function() {
						sibling.remove();
						el.show();
						this.hideLoading();
					},
					failure	: Ext.emptyFn
				});
	},

	showUpdating	: function() {
		var controller = Kohive.OS.getController('photos');
		var view = controller.indexWindow || null;

		if (view)
			view.showUpdating();
	},

	/**
	 * Hides the loading animation from the view
	 */
	hideLoading		: function() {
		var controller = Kohive.OS.getController('photos');
		var view = controller.indexWindow || null;

		if (view) {
			view.hideLoading();
			view.fireEvent('update-filter-bar', view.cachedStore);
		};
	},

	/**
	 * Refreshes the content in the view
	 */
	refreshView		: function() {
		var controller = Kohive.OS.getController('photos');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.store.load();
		if (view)
			view.hideLoading();
	}
}
);

/**
 * @class Kohive.models.MicroBlog
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.MicroBlog", {
	modelName		: 'microblog',
	fields			: [{
				name	: 'twitter_id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'hive_id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'nickname',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'created_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'modified_at',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'author_avatar',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'toggled',
				type	: 'boolean',
				virtual	: true
			}, {
				name	: 'toggled_comments',
				type	: 'boolean',
				virtual	: true
			},

			{
				name	: 'comments',
				virtual	: true,
				convert	: function(value, record) {
					if (value)
						return value;
					else
						[];
				}
			}, {
				name	: 'new_comment',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'hide_comments',
				type	: 'boolean',
				virtual	: true
			},

			{
				name	: 'body',
				convert	: function(value, record) {
					var url = "<br />";

					// get the twitpic links
					var urls = value
							.match(new RegExp(
									"(http:\/\/[www\.]*[a-zA-Z0-9\-\_]*\.[a-z]{2,3}[\.a-z]{3,4}[\-\/\?\=\+\.\_a-zA-Z0-9]*)",
									'g'
							))
							|| [];
					Ext.each(urls, function(link) {
						var twitpic = (link.split('twitpic.com/')) ? link
								.split('twitpic.com/')[1] : null;
						var yfrog = (link.split('yfrog.com/')) ? link
								.split('yfrog.com/')[1] : null;

						// add the url
						if (twitpic)
							url += '<a href="'
									+ link
									+ '" align="left"><img class="img" src="http://twitpic.com/show/mini/'
									+ twitpic + '" /></a>&nbsp;';
						if (yfrog)
							url += '<a href="'
									+ link
									+ '" align="left"><img class="img" src="http://yfrog.com/'
									+ yfrog + '.th.jpg" /></a>&nbsp;';
					}, this
					);

					// add the urls
					if (urls.length > 0)
						value += url;

					return value;
				}
			},

			{
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at, true);
				}
			},

			// editable properties
			{
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// recipient
					// mod/owner
					if (Kohive.OS.isAuthor(record)
							|| Kohive.OS.isCustom(record,
									'assignee_membership_id', 'id'
							) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}, {
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// mod/owner
					// if (Kohive.OS.isAuthor(record) || Kohive.OS.isHiveMod()) return true;
					return false;
				}
			}],

	dataView		: new Ext.XTemplate(
			'<div class="x-pod-wrap">',
			'<tpl for=".">',
			'<div id="microblog-{id}" class="x-pod x-microblog">',
			'<div class="x-content-wrap">',
			'<div class="x-control-wrap"><div class="x-control"><div></div></div></div>',
			'<div class="x-content">',
			'<div class="x-title"><div class="x-title">{author_nickname}</div></div>',
			// '<div class="x-title"><div class="x-title">{nickname}</div><div class="x-reply-btn action-click-reply"></div></div>',
			'<tpl if="!toggled">',
			'<div class="x-extra">',
			'<div class="x-message">',
			'<div class="x-avatar">',
			'<img src="{author_avatar}" />',
			'</div>',
			'<div class="action-edit-body">{body}</div>',
			'<div class="x-clearfix"></div>',
			'</div>',
			'<div class="x-other">',
			'<div class="x-created-on">' + '{created_at_date}</div>',
			'</div>',
			'</div>',
			'</tpl>',
			'</div>',
			'<div class="x-delete-wrap"><div class="x-delete"><div class="action-delete"></div></div></div>',
			'</div>',

			'<tpl if="!toggled">',
			'<div class="x-comments<tpl if="this.isSmall(comments, toggled_comments, new_comment)"> x-small</tpl><tpl if="this.hasComments(comments)"> x-hascomments</tpl><tpl if="new_comment"> x-adding-comment</tpl>">',
			'<tpl if="!toggled_comments">',
			'<tpl for="comments">',
			'<div class="x-comment" id="microblog-comment-{#}-{id}">',
			'<div class="x-delete-comment"><div></div></div>',
			'<div class="x-author"><img src="{thumb_filename}" /> {[Kohive.OS.isAuthor(values) ? Ext.ux.Translator.translate("me") : values.author_nickname]}</div>',
			'<div class="x-body">{content}</div>',
			'<div class="x-date">{[(values.created_at.split("T")[1]) ? Kohive.OS.convertToDate(values.created_at, true) : values.created_at]}</div>',
			'</div>',
			'</tpl>',
			'</tpl>',
			'<tpl if="!this.isSmall(comments, toggled_comments, new_comment)">',
			'<div class="x-new-comment<tpl if="this.hasComments(comments)"> x-extended</tpl><tpl if="new_comment"> x-is-field</tpl>">',
			'<tpl if="!new_comment && this.hasComments(comments)"><div class="x-toggle-button"><div class="x-img"></div></div></tpl>',
			'<tpl if="!new_comment"><div class="x-button"><div class="x-img"></div></div></tpl>',
			'<tpl if="new_comment">',
			'<div class="x-field"><input type="text" /></div>',
			'<div class="x-submit"><span>'
					+ Ext.ux.Translator.translate('post') + '</span></div>',
			'</tpl>',
			'</div>',
			'</tpl>',
			'<tpl if="this.isSmall(comments, toggled_comments, new_comment)">',
			'<div class="x-new-comment x-small">',
			'<tpl if="this.hasComments(comments)"><div class="x-toggle-button toggled"><div class="x-img"></div><span class="x-txt">{[this.commentsLength(values.comments)]}</span></div></tpl>',
			'<tpl if="!this.hasComments(comments)"><div class="x-button"><div class="x-img"></div><span class="x-txt">{[Ext.ux.Translator.translate("new_comment")]}</span></div></tpl>',
			'</div>', '</tpl>', '</div>', '</tpl>',

			{
				isSmall			: function(comments, toggled_comments,
						new_comment) {
					if (new_comment)
						return false;
					if (comments.length == 0 && toggled_comments)
						return true;
					if (comments.length == 0 && !toggled_comments)
						return true;
					if (comments.length > 0 && toggled_comments)
						return true;
					return false;
				},
				hasComments		: function(comments) {
					return comments.length > 0;
				},
				commentsLength	: function(comments) {
					var length = comments.length;
					if (comments.length == 0)
						return length + " "
								+ Ext.ux.Translator.translate('comments');
					if (comments.length == 1)
						return length + " "
								+ Ext.ux.Translator.translate('comment');
					if (comments.length > 1)
						return length + " "
								+ Ext.ux.Translator.translate('comments');
				}
			},

			'</div>', '</tpl>', '</div>'
	),

	clickActions	: [
			// {
			// name: 'body',
			// type: 'edit',
			// fieldType: 'textarea',
			// method: 'dblclick'
			// },
			{
		name	: 'reply',
		type	: 'reply',
		method	: 'click'
	}]
}
);

/**
 * @class Kohive.models.Overview
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Overview", {
	modelName	: 'overview',
	fields		: [{
				name	: 'other',
				type	: 'string'
			}, {
				name	: 'other2',
				type	: 'string'
			}, {
				name	: 'extra_old',
				type	: 'string'
			}, {
				name	: 'extra_new',
				type	: 'string'
			}, {
				name	: 'reference_type',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'author_id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'author_avatar',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'event_type',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_id)
						return value;
					if (id == record.author_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at, true);
				}
			}, {
				name	: 'icon',
				virtual	: true,
				convert	: function(value, record) {
					var name = record.reference_type.toLowerCase(), path = "";

					if (name == "hive")
						path = "/images/apps/Overview/" + name + ".png";
					else if (name == "membership")
						path = record.author_avatar;
					else if (name == "image" || name == "comment"
							|| name == "album")
						path = "/images/components/ApplicationLauncher/icons/photos.png";
					else if (name == "blog")
						path = "/images/components/ApplicationLauncher/icons/blog.png";
					else if (name == "filecabinet")
						path = "/images/components/ApplicationLauncher/icons/filecabinet.png";
					else if (name == "videoalbum")
						path = "/images/components/ApplicationLauncher/icons/videos.png";
					else
						path = "/images/components/ApplicationLauncher/icons/"
								+ name.pluralize() + ".png";

					return path;
				}
			}, {
				name	: 'translation',
				virtual	: true,
				convert	: function(value, record) {
					var tr = (record.reference_type == "Task" && record.event_type == "update_status")
							? 'event_' + record.reference_type.toLowerCase()
									+ '_' + record.event_type.toLowerCase()
									+ '_' + record.extra_new
							: 'event_' + record.reference_type.toLowerCase()
									+ '_' + record.event_type.toLowerCase();
					if (tr == "event_image_destroy")
						console.log();

					return Ext.ux.Translator.translate(tr, {
								title			: record.other,
								author_nickname	: record.author_nickname,
								other			: record.other2,
								extra_old		: record.extra_old,
								extra_new		: record.extra_new,
								created_at		: record.created_at_date
							});
				}
			}
	// {
	// name: 'id_card',
	// virtual: true,
	// convert: function(value, record) {
	// return Kohive.OS.getIdCardFromMembershipId(record.author_membership_id);
	// }
	// }
	]
}
);

/**
 * @class Kohive.models.Sticky
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Sticky", {
	modelName		: 'sticky',
	fields			: [{
				name	: 'id',
				type	: 'int'
			}, {
				name	: 'body',
				type	: 'string'
			}, {
				name	: 'body_html',
				type	: 'string'
			}, {
				name	: 'color',
				type	: 'string'
			}, {
				name	: 'stamp',
				type	: 'string'
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'created_at',
				type	: 'string'
			}, {
				name	: 'modified_at',
				type	: 'string'
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'toggled',
				type	: 'boolean',
				virtual	: true
			},

			{
				name	: 'color_cls',
				virtual	: true,
				convert	: function(value, record) {
					return record.color + (Math.floor(Math.random() * 3) + 1);
				}
			}, {
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at, true);
				}
			},

			// editable properties
			{
				name	: 'can_drag',
				virtual	: true,
				convert	: function(value, record) {
					// is not used already
					if (Kohive.OS.stickyDropAllowed({
								data	: record
							}))
						return true;
					return false;
				}
			}, {
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// return true always until proper checking can be done
					return true;

					// author
					// recipient
					// mod/owner
					if (Kohive.OS.isAuthor(record))
						return true;
					return false;
				}
			}, {
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// mod/owner
					if (Kohive.OS.isAuthor(record) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}],

	dataView		: new Ext.XTemplate(
			'<div class="x-pod-wrap">',
			'<tpl for=".">',
			'<div id="sticky-{id}" class="x-sticky {color} {color_cls} x-pod<tpl if="can_delete"> x-deletable-hover</tpl><tpl if="can_drag"> x-dragable</tpl>">',
			'<div class="x-stamp<tpl if="stamp"> {stamp}</tpl>">',
			'<div class="x-created">{author_nickname}, {created_at_date}</div>',
			'<div class="x-delete-wrap"><div class="x-delete"><div class="action-delete"></div></div></div>',
			'</div>', '<div id="middle" class="x-sticky-wrap">',
			'<div id="inner" class="x-sticky-inner-wrap">',
			'<div class="x-body action-edit-body">{body_html}</div>', '</div>',
			'</div>', '</div>', '</tpl>', '</div>'
	),

	clickActions	: [{
				name			: 'body',
				value			: 'body',
				type			: 'edit',
				fieldType		: 'textarea',
				method			: 'dblclick',
				forceRefresh	: true
			}]
}
);

/**
 * @class Kohive.models.Task
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Task", {
	modelName		: 'task',
	fields			: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'title',
				type	: 'string'
			}, {
				name	: 'body',
				type	: 'string'
			}, {
				name	: 'body_html',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'due',
				type	: 'string'
			}, {
				name	: 'author_membership_id',
				type	: 'int'
			}, {
				name	: 'assignee_membership_id',
				type	: 'int'
			}, {
				name	: 'created_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'modified_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'completed_at',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'milestone_id',
				type	: 'int'
			}, {
				name	: 'milestone',
				virtual	: true
			},

			{
				name	: 'file_cabinet_id',
				type	: 'int'
			}, {
				name	: 'file_cabinet',
				virtual	: true
			},

			{
				name	: 'toggled',
				type	: 'boolean',
				virtual	: true
			}, {
				name	: 'toggled_comments',
				type	: 'boolean',
				virtual	: true
			},

			{
				name	: 'width',
				virtual	: true
			},

			{
				name	: 'comments',
				virtual	: true,
				convert	: function(value, record) {
					if (value)
						return value;
					else
						[];
				}
			}, {
				name	: 'new_comment',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'hide_comments',
				type	: 'boolean',
				virtual	: true
			},

			{
				name	: 'title_trimmed',
				virtual	: true,
				convert	: function(value, record) {
					if (!value)
						return record.title;
					return value;
				}
			},

			{
				name	: 'type',
				type	: 'int'
			}, {
				name	: 'task_type',
				type	: 'int'
			}, {
				name	: 'type_string',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var value = (record.type == null) ? 0 : record.type, valueString = 0;

					switch (value) {
						case 0 :
							valueString = "null";
							break;

						case 1 :
							valueString = "cube";
							break;

						case 2 :
							valueString = "star";
							break;

						case 3 :
							valueString = "spider";
							break;

						case 4 :
							valueString = "bug";
							break;

						case 5 :
							valueString = "brush";
							break;

						case 6 :
							valueString = "console";
							break;

						case 7 :
							valueString = "tool";
							break;

						case 8 :
							valueString = "colors";
							break;
					};

					return valueString;
				}
			},

			{
				name	: 'flagged',
				type	: 'boolean'
			}, {
				name	: 'flagged_string',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var value = (record.flagged == null)
							? false
							: record.flagged, valueString = "";

					switch (value) {
						case false :
							valueString = "false";
							break;

						case true :
							valueString = "true";
							break;
					};

					return valueString;
				}
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			}, {
				name	: 'assignee_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.assignee_membership_id)
						return value;
					if (id == record.assignee_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'state',
				convert	: function(value, record) {
					// TODO check if it is overdue
					return value;
				}
			},

			{
				name	: 'priority',
				convert	: function(value, record) {
					return (value == null) ? 1 : value;
				}
			}, {
				name	: 'priority_string',
				virtual	: true,
				convert	: function(value, record) {
					value = (record.priority == null) ? 1 : record.priority;
					var valueString;

					switch (value) {
						case 1 :
							valueString = "low";
							break;

						case 2 :
							valueString = "medium";
							break;

						case 3 :
							valueString = "high";
							break;
					};

					return valueString;
				}
			},

			{
				name	: 'effort',
				convert	: function(value, record) {
					return (value == null) ? 1 : value;
				}
			}, {
				name	: 'effort_string',
				virtual	: true,
				convert	: function(value, record) {
					value = (record.effort == null) ? 1 : record.effort;
					var valueString;

					switch (value) {
						case 1 :
							valueString = "low";
							break;

						case 2 :
							valueString = "medium";
							break;

						case 3 :
							valueString = "high";
							break;
					};

					return valueString;
				}
			},

			{
				name	: 'overdue',
				virtual	: true,
				convert	: function(value, record) {
					// Check if a due date is set, as if none is set it cant be overdue
					if (!record.due)
						return;

					// Convert the due date into a proper JS date, and get the current date
					var dueDate = Kohive.OS.convertToDate(record.due);
					var currentDate = new Date();

					// Check if the due date is below or lower than the current date
					if (dueDate < currentDate && record.state == "new")
						return true;

					return false;
				}
			},

			{
				name	: 'tag_list',
				convert	: function(value, record) {
					if (!value && record.tags.length > 0) {
						var res = "";
						Ext.each(record.tags, function(tag) {
									res += tag.name + " ";
								}, this);
						return res;
					} else {
						return value;
					}
				}
			}, {
				name	: 'tags',
				virtual	: true,
				convert	: function(value, record) {
					if (value.length < 1)
						value = false;

					return value;
				}
			},

			{
				name	: 'completed_at_date',
				virtual	: true,
				convert	: function(value, record) {
					if (!record.completed_at)
						return false;
					return Kohive.OS.convertToDate(record.completed_at, true);
				}
			}, {
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at, true);
				}
			}, {
				name	: 'due_date',
				virtual	: true,
				convert	: function(value, record) {
					if (record.due)
						return Kohive.OS.convertToDate(record.due, true);
					else
						return false;
				}
			}, {
				name	: 'due_normal',
				virtual	: true,
				convert	: function(value, record) {
					if (record.due)
						return Kohive.OS.convertToDate(record.due, false);
					else
						return false;
				}
			},

			// editable properties
			{
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// return true always until proper checking can be done
					return true;

					// author
					// recipient
					// mod/owner
					if (Kohive.OS.isAuthor(record)
							|| Kohive.OS.isCustom(record,
									'assignee_membership_id', 'id'
							) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}, {
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// mod/owner
					if (Kohive.OS.isAuthor(record)
							|| Kohive.OS.isCustom(record,
									'assignee_membership_id', 'id'
							) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}],

	hasMany			: "Comment",

	dataView		: new Ext.XTemplate(
			'<div class="x-pod-wrap">',
			'<tpl for=".">',

			'<div id="task-{id}" class="x-pod x-task {state}<tpl if="overdue"> overdue</tpl><tpl if="can_edit"> x-editable-hover</tpl><tpl if="can_delete"> x-deletable-hover</tpl>">',
			'<div class="x-content-wrap">',

			'<div class="x-control-wrap"><div class="x-control<tpl if="toggled"> hidden</tpl>"><div></div></div></div>',

			'<div class="x-content">',
			'<div class="x-title">',
			'<div class="x-state action-updateState-state {state}"></div>',
			'<div class="x-title action-edit-title {state}">{[(values.title_trimmed) ? values.title_trimmed : values.title]}</div>',

			'<tpl if="toggled">',
			'<div class="x-toggle-extra">',
			'<tpl if="tags"><span class="x-tag"></span></tpl>',
			'<tpl if="body"><span class="x-note"></span></tpl>',
			'<span class="x-type action-updateType-type {type_string}"></span>',
			'<span class="x-priority action-updatePriority-priority {priority_string}"></span>',
			'<span class="x-effort action-updateEffort-effort {effort_string}"></span>',
			'<span class="x-flagged action-updateFlagged-flagged {flagged_string}"></span>',
			'</div>',
			'</tpl>',
			'<tpl if="!toggled">',
			'<div class="x-toggle-extra">',
			'<span class="x-type action-updateType-type {type_string}"></span>',
			'<span class="x-priority action-updatePriority-priority {priority_string}"></span>',
			'<span class="x-effort action-updateEffort-effort {effort_string}"></span>',
			'<span class="x-flagged action-updateFlagged-flagged {flagged_string}"></span>',
			'</div>',
			'</tpl>',
			'</div>',

			'<tpl if="!toggled">',
			'<div class="x-extra">',
			'<tpl if="assignee_nickname || can_edit">',
			'<div class="x-stuff">',
			'<div class="x-assignee action-assignedPicker-assignee_nickname {state}<tpl if="!assignee_nickname && can_edit"> empty</tpl>">',
			'<tpl if="assignee_nickname">{assignee_nickname}</tpl><tpl if="!assignee_nickname && can_edit">'
					+ Ext.ux.Translator.translate('app_tasks_add_assignee')
					+ '</tpl>',
			'</div>',
			'</div>',
			'</tpl>',
			'<tpl if="due_date || can_edit">',
			'<div class="x-stuff date">',
			'<tpl if="due_date"><div class="x-due action-duePicker-due">{due_date}</div><div class="x-due-icon"></div></tpl>',
			'<tpl if="!due_date && can_edit"><div class="x-due x-empty action-duePicker-due">'
					+ Ext.ux.Translator.translate('app_tasks_add_due_date')
					+ '</div><div class="x-due-icon"></div></tpl>',
			'</div>',
			'</tpl>',
			'<tpl if="milestone || can_edit">',
			'<div class="x-stuff milestone">',
			'<tpl if="milestone"><div class="x-milestone action-milestonePicker-milestone"><tpl for="milestone">{title}</tpl> </div><div class="x-milestone-icon"></div></tpl>',
			'<tpl if="!milestone && can_edit"><div class="x-milestone x-empty action-milestonePicker-milestone">'
					+ Ext.ux.Translator.translate('app_tasks_add_milestone')
					+ '</div><div class="x-milestone-icon"></div></tpl>',
			'</div>',
			'</tpl>',
			'<tpl if="body">',
			'<div class="x-description"><div class="action-edit-body">{body_html}</div></div>',
			'</tpl>',
			'<tpl if="!body && can_edit">',
			'<div class="x-description x-empty"><div class="action-edit-body">'
					+ Ext.ux.Translator.translate('app_add_description')
					+ '</div></div>',
			'</tpl>',
			'<tpl if="file_cabinet || can_edit">',
			'<div class="x-stuff file">',
			'<div class="x-file action-filesPicker-file_id<tpl if="!file_cabinet && can_edit"> empty</tpl>">',
			'<tpl if="file_cabinet"><tpl for="file_cabinet">{title}</tpl></tpl><tpl if="!file_cabinet && can_edit">'
					+ Ext.ux.Translator.translate('app_tasks_file') + '</tpl>',
			'</div>',
			'</div>',
			'</tpl>',
			'<tpl if="tags">',
			'<div class="x-tags">',
			'<div class="action-editTags-tags">',
			'<div class="x-form-field-wrap x-trigger-field-wrap">',
			'<div class="x-form-text x-superboxselect  x-superboxselect-display-btns">',
			'<ul>',
			'<tpl for="tags">',
			'<li class="x-superboxselect-item no-close">{name}</li>',
			'</tpl>',
			'</ul>',
			'</div>',
			'</div>',
			'</div>',
			'</div>',
			'</tpl>',
			'<tpl if="!tags && can_edit">',
			'<div class="x-tags x-empty"><div class="action-editTags-tags">'
					+ Ext.ux.Translator.translate('app_add_tags')
					+ '</div></div>',
			'</tpl>',
			'<div class="x-other">',
			'<div class="x-created-on">'
					+ '{author_nickname}, {created_at_date}</div>',
			'<tpl if="completed_at_date"><div class="x-created-by">'
					+ Ext.ux.Translator.translate('completed_on')
					+ ' {completed_at_date}</div></tpl>',
			'</div>',
			'</div>',
			'</tpl>',

			'</div>',
			'<div class="x-delete-wrap"><div class="x-delete"><div class="action-delete"></div></div></div>',
			'</div>',

			'<tpl if="!toggled">',
			'<div class="x-comments<tpl if="this.isSmall(comments, toggled_comments, new_comment)"> x-small</tpl><tpl if="this.hasComments(comments)"> x-hascomments</tpl><tpl if="new_comment"> x-adding-comment</tpl>">',
			'<tpl if="!toggled_comments">',
			'<tpl for="comments">',
			'<div class="x-comment" id="task-comment-{#}-{id}">',
			'<div class="x-delete-comment"><div></div></div>',
			'<div class="x-author"><img src="{thumb_filename}" /> {[Kohive.OS.isAuthor(values) ? Ext.ux.Translator.translate("me") : values.author_nickname]}</div>',
			'<div class="x-body">{content}</div>',
			'<div class="x-date">{[(values.created_at.split("T")[1]) ? Kohive.OS.convertToDate(values.created_at, true) : values.created_at]}</div>',
			'</div>',
			'</tpl>',
			'</tpl>',
			'<tpl if="!this.isSmall(comments, toggled_comments, new_comment)">',
			'<div class="x-new-comment<tpl if="this.hasComments(comments)"> x-extended</tpl><tpl if="new_comment"> x-is-field</tpl>">',
			'<tpl if="!new_comment && this.hasComments(comments)"><div class="x-toggle-button"><div class="x-img"></div></div></tpl>',
			'<tpl if="!new_comment"><div class="x-button"><div class="x-img"></div></div></tpl>',
			'<tpl if="new_comment">',
			'<div class="x-field"><input type="text" /></div>',
			'<div class="x-submit"><span>'
					+ Ext.ux.Translator.translate('post') + '</span></div>',
			'</tpl>',
			'</div>',
			'</tpl>',
			'<tpl if="this.isSmall(comments, toggled_comments, new_comment)">',
			'<div class="x-new-comment x-small">',
			'<tpl if="this.hasComments(comments)"><div class="x-toggle-button toggled"><div class="x-img"></div><span class="x-txt">{[this.commentsLength(values.comments)]}</span></div></tpl>',
			'<tpl if="!this.hasComments(comments)"><div class="x-button"><div class="x-img"></div><span class="x-txt">{[Ext.ux.Translator.translate("new_comment")]}</span></div></tpl>',
			'</div>', '</tpl>', '</div>', '</tpl>',

			{
				isSmall			: function(comments, toggled_comments,
						new_comment) {
					if (new_comment)
						return false;
					if (comments.length == 0 && toggled_comments)
						return true;
					if (comments.length == 0 && !toggled_comments)
						return true;
					if (comments.length > 0 && toggled_comments)
						return true;
					return false;
				},
				hasComments		: function(comments) {
					return comments.length > 0;
				},
				commentsLength	: function(comments) {
					var length = comments.length;
					if (comments.length == 0)
						return length + " "
								+ Ext.ux.Translator.translate('comments');
					if (comments.length == 1)
						return length + " "
								+ Ext.ux.Translator.translate('comment');
					if (comments.length > 1)
						return length + " "
								+ Ext.ux.Translator.translate('comments');
				}
			},

			'</div>', '</tpl>', '</div>'
	),

	clickActions	: [{
				name		: 'title',
				value		: 'title',
				type		: 'edit',
				method		: 'dblclick',
				allowBlank	: false
			}, {
				name	: 'assignee_nickname',
				method	: 'dblclick',
				type	: 'assignedPicker'
			}, {
				name			: 'file_id',
				method			: 'dblclick',
				forceRefresh	: true,
				type			: 'filesPicker'
			}, {
				name			: 'due',
				method			: 'dblclick',
				type			: 'duePicker',
				forceRefresh	: true
			}, {
				name			: 'milestone',
				method			: 'dblclick',
				type			: 'milestonePicker',
				forceRefresh	: true
			}, {
				name			: 'body',
				value			: 'body',
				type			: 'edit',
				fieldType		: 'textarea',
				forceRefresh	: true,
				method			: 'dblclick',
				emptyText		: Ext.ux.Translator
						.translate('app_tasks_add_description')
			}, {
				name	: 'tags',
				type	: 'editTags',
				method	: 'dblclick'
			}, {
				name	: 'state',
				type	: 'updateState',
				method	: 'click'
			}, {
				name	: 'priority',
				type	: 'updatePriority',
				method	: 'click'
			}, {
				name	: 'effort',
				type	: 'updateEffort',
				method	: 'click'
			}, {
				name	: 'type',
				type	: 'updateType',
				method	: 'click'
			}, {
				name	: 'flagged',
				type	: 'updateFlagged',
				method	: 'click'
			}],

	timer			: {},

	/**
	 * Updates the state of the selected task
	 */
	updateState		: function(dataview, record, el, a, index) {
		if (!record.get('can_edit'))
			return;

		var newState, state = record.get('state');

		// Get the new state
		switch (state) {
			case 'new' :
				newState = 'pending';
				break;

			case 'pending' :
				newState = 'completed';
				break;

			case 'completed' :
				newState = 'invalid';
				break;

			case 'invalid' :
				newState = 'new';
				break;
		};

		// update the state
		record.set('state', newState);

		// update the comepleted_at date if the state has changed
		if (newState == "completed") {
			record.set('completed_at_date', new Date().format(Kohive.OS
							.getDefaultDateFormat()));
		} else {
			record.set('completed_at_date', null);
		};

		var scope = this;

		clearTimeout(this.timer['state']);
		this.timer['state'] = setTimeout(function() {
					scope.showUpdating();

					// Update the record with the new state value
					record.update({
								state	: newState
							}, {
								url		: '/memberships/'
										+ Kohive.OS.getCurrentHive().get('id')
										+ '/tasks/' + record.get('id'),
								success	: scope.hideLoading,
								failure	: function() {
									record.set('state', state);
									return Ext.Msg.alert('Error',
											'Sorry, something went wrong. Please try again'
									);
								}
							});
				}, 2000);
	},

	/**
	 * Updates the priority of the selected task
	 */
	updatePriority	: function(dataview, record, el, a, index) {
		if (!record.get('can_edit'))
			return;

		var newPriority, newPriorityString, priority = record.get('priority'), priorityString = record
				.get('priority_string');

		// Get the new state
		switch (priority) {
			case 1 :
				newPriority = 2;
				break;

			case 2 :
				newPriority = 3;
				break;

			case 3 :
				newPriority = 1;
				break;
		};

		switch (newPriority) {
			case 1 :
				newPriorityString = "low";
				break;

			case 2 :
				newPriorityString = "medium";
				break;

			case 3 :
				newPriorityString = "high";
				break;
		};

		// update the priority
		record.set('priority', newPriority);
		record.set('priority_string', newPriorityString);

		var scope = this;

		clearTimeout(this.timer['priority']);
		this.timer['priority'] = setTimeout(function() {
					scope.showUpdating();

					// Update the record with the new state value
					record.update({
								priority		: newPriority,
								priority_string	: newPriorityString
							}, {
								url		: '/memberships/'
										+ Kohive.OS.getCurrentHive().get('id')
										+ '/tasks/' + record.get('id'),
								success	: scope.hideLoading,
								failure	: function() {
									record.set('priority', priority);
									record.set('priority_string',
											priorityString
									);
									return Ext.Msg.alert('Error',
											'Sorry, something went wrong. Please try again'
									);
								}
							});
				}, 2000);
	},

	/**
	 * Updates the effort of the selected task
	 */
	updateEffort	: function(dataview, record, el, a, index) {
		if (!record.get('can_edit'))
			return;

		var newEffort, newEffortString, effort = record.get('effort'), effortString = record
				.get('effort_string');

		// Get the new state
		switch (effort) {
			case 1 :
				newEffort = 2;
				break;

			case 2 :
				newEffort = 3;
				break;

			case 3 :
				newEffort = 1;
				break;
		};

		switch (newEffort) {
			case 1 :
				newEffortString = "low";
				break;

			case 2 :
				newEffortString = "medium";
				break;

			case 3 :
				newEffortString = "high";
				break;
		};

		// update the effort
		record.set('effort', newEffort);
		record.set('effort_string', newEffortString);

		var scope = this;

		clearTimeout(this.timer['effort']);
		this.timer['effort'] = setTimeout(function() {
					scope.showUpdating();

					// Update the record with the new state value
					record.update({
								effort			: newEffort,
								effort_string	: newEffortString
							}, {
								url		: '/memberships/'
										+ Kohive.OS.getCurrentHive().get('id')
										+ '/tasks/' + record.get('id'),
								success	: scope.hideLoading,
								failure	: function() {
									record.set('effort', effort);
									record.set('effort_string', effortString);
									return Ext.Msg.alert('Error',
											'Sorry, something went wrong. Please try again'
									);
								}
							});
				}, 2000);
	},

	/**
	* Updates the type of the selected task
	*/
	updateType		: function(dataview, record, el, a, index) {
		if (!record.get('can_edit'))
			return;

		var newType, newTypeString, type = (record.get('type')) ? record
				.get('type') : 0, typeString = record.get('type_string');

		// Get the new state
		switch (type) {
			case 0 :
				newType = 1;
				break;

			case 1 :
				newType = 2;
				break;

			case 2 :
				newType = 3;
				break;

			case 3 :
				newType = 4;
				break;

			case 4 :
				newType = 5;
				break;

			case 5 :
				newType = 6;
				break;

			case 6 :
				newType = 7;
				break;

			case 7 :
				newType = 8;
				break;

			case 8 :
				newType = 0;
				break;
		};

		switch (newType) {
			case 0 :
				newTypeString = "null";
				break;

			case 1 :
				newTypeString = "cube";
				break;

			case 2 :
				newTypeString = "star";
				break;

			case 3 :
				newTypeString = "spider";
				break;

			case 4 :
				newTypeString = "bug";
				break;

			case 5 :
				newTypeString = "brush";
				break;

			case 6 :
				newTypeString = "console";
				break;

			case 7 :
				newTypeString = "tool";
				break;

			case 8 :
				newTypeString = "colors";
				break;
		};

		// update the priority
		record.set('type', newType);
		record.set('type_string', newTypeString);

		var scope = this;

		clearTimeout(this.timer['type']);
		this.timer['type'] = setTimeout(function() {
					scope.showUpdating();

					// Update the record with the new type value
					record.update({
								type		: newType,
								type_string	: newTypeString
							}, {
								url		: '/memberships/'
										+ Kohive.OS.getCurrentHive().get('id')
										+ '/tasks/' + record.get('id'),
								success	: scope.hideLoading,
								failure	: function() {
									record.set('type', type);
									record.set('type_string', typeString);
									return Ext.Msg.alert('Error',
											'Sorry, something went wrong. Please try again'
									);
								}
							});
				}, 2000);
	},

	/**
	 * Updates the flagged state of the selected task
	 */
	updateFlagged	: function(dataview, record, el, a, index) {
		if (!record.get('can_edit'))
			return;

		var newFlagged, newFlaggedString, flagged = (record.get('flagged'))
				? 1
				: 0, flaggedString = record.get('flagged_string');

		// Get the new state
		switch (flagged) {
			case 0 :
				newFlagged = 1;
				break;

			case 1 :
				newFlagged = 0;
				break;
		};

		switch (newFlagged) {
			case 0 :
				newFlaggedString = "false";
				break;

			case 1 :
				newFlaggedString = "true";
				break;
		};

		// update the flagged
		record.set('flagged', newFlagged);
		record.set('flagged_string', newFlaggedString);

		var scope = this;

		clearTimeout(this.timer['flagged']);
		this.timer['flagged'] = setTimeout(function() {
					scope.showUpdating();

					// Update the record with the new type value
					record.update({
								flagged			: newFlagged,
								flagged_string	: newFlaggedString
							}, {
								url		: '/memberships/'
										+ Kohive.OS.getCurrentHive().get('id')
										+ '/tasks/' + record.get('id'),
								success	: scope.hideLoading,
								failure	: function() {
									record.set('flagged', flagged);
									record.set('flagged_string', flaggedString);
									return Ext.Msg.alert('Error',
											'Sorry, something went wrong. Please try again'
									);
								}
							}
					);
				}, 2000
		);
	},

	showUpdating	: function() {
		var controller = Kohive.OS.getController('tasks');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.showUpdating();
	},

	/**
	 * Hides the loading animation from the view
	 */
	hideLoading		: function() {
		var controller = Kohive.OS.getController('tasks');
		var view = controller.indexWindow || null;

		if (view) {
			view.hideLoading();
			// view.fireEvent('update-filter-bar', view.cachedStore);
		};
	},

	/**
	 * Refreshes the content in the view
	 */
	refreshView		: function() {
		var controller = Kohive.OS.getController('tasks');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.store.load();
		if (view)
			view.hideLoading();
	},

	/**
	 * Creates a new combobox for gender
	 */
	assignedPicker	: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-assignedTo-field',
					cls	: 'assigned_to-field'
				});

		el.enableDisplayMode();
		el.hide();

		var memberships = [[Ext.ux.Translator.translate('none'), null]];

		Ext.each(Kohive.OS.getCurrentHiveMemberships(), function(membership) {
					if (membership.get('state') == 'active') {
						memberships.push([membership.get('id_card').full_name,
								membership.get('id'),
								membership.get('id_card').nickname]);
					};
				}, this);

		var membershipsStore = new Ext.data.SimpleStore({
					fields	: ['alias', 'assignee_membership_id', 'nickname'],
					data	: memberships
				});

		var field = new Ext.form.ComboBox({
					renderTo		: 'edit-assignedTo-field',
					name			: 'assignee_membership_id',
					displayField	: 'alias',
					valueField		: 'assignee_membership_id',
					value			: record.get('assignee_membership_id'),
					width			: 110,
					store			: membershipsStore,
					selectOnFocus	: true,
					triggerAction	: 'all',
					typeAhead		: true,
					emptyText		: '',
					mode			: 'local',
					listeners		: {
						scope		: this,
						'blur'		: function() {
							sibling.remove();
							el.show();
						},
						'select'	: function(field, r) {
							record.set('assignee_nickname', r.get('nickname'));
							record.set('assignee_membership_id', r
											.get('assignee_membership_id'));

							sibling.remove();
							el.show();

							record.save({
										url		: '/memberships/'
												+ Kohive.OS.getCurrentHive()
														.get('id') + '/tasks/'
												+ record.get('id'),
										scope	: this,
										success	: function() {

										},
										failure	: function() {

										}
									});
						}
					}
				});

		var tempTask = new Ext.util.DelayedTask(function() {
					field.focus();
					field.el.unselectable();
				}, this);
		tempTask.delay(100);
	},

	filesPicker		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-files-field',
					cls	: 'files-field'
				});

		el.enableDisplayMode();
		el.hide();

		var store = Kohive.OS.getController('tasks').files[Kohive.OS
				.getCurrentHiveId()];

		var field = new Ext.form.ComboBox({
			renderTo		: 'edit-files-field',
			name			: 'file_cabinet_id',
			hiddenName		: 'file_cabinet_id',
			triggerAction	: 'all',
			mode			: 'local',
			displayField	: 'title',
			valueField		: 'id',
			selectOnFocus	: true,
			forceSelection	: true,
			enableKeyEvents	: true,
			store			: store,
			value			: (record.get('file_cabinet_id') == 0)
					? null
					: record.get('file_cabinet_id'),
			width			: 110,
			listeners		: {
				scope		: this,
				'blur'		: function() {
					sibling.remove();
					el.show();
				},
				'select'	: function(field, r) {
					// if the user selected none, do nothing
					if (record.get('file_cabinet_id') == r.get('id'))
						return;

					record.set('file_cabinet_id', (r.get('id'))
									? r.get('id')
									: 0);

					this.showUpdating();

					record.save({
						url		: '/memberships/'
								+ Kohive.OS.getCurrentHive().get('id')
								+ '/tasks/' + record.get('id'),
						scope	: this,
						success	: function(model, response) {
							var task = Ext.decode(response.responseText);
							record.set('file_cabinet_id', task.file_cabinet_id);
							record.set('file_cabinet', task.file_cabinet);
							record.set('title', "");
							record.set('title', task.title);

							sibling.remove();
							el.show();

							this.hideLoading();
						},
						failure	: function() {
							this.showFailure();
						}
					}
					);
				}
			}
		}
		);

		var tempTask = new Ext.util.DelayedTask(function() {
					field.focus();
					field.el.unselectable();
				}, this);
		tempTask.delay(100);
	},

	milestonePicker	: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-milestones-field',
					cls	: 'milestones-field'
				});

		el.enableDisplayMode();
		el.hide();

		var store = Kohive.OS.getController('tasks').milestones[Kohive.OS
				.getCurrentHiveId()];

		var field = new Ext.form.ComboBox({
			renderTo		: 'edit-milestones-field',
			name			: 'milestone_id',
			hiddenName		: 'milestone_id',
			triggerAction	: 'all',
			mode			: 'local',
			displayField	: 'title',
			valueField		: 'id',
			selectOnFocus	: true,
			forceSelection	: true,
			enableKeyEvents	: true,
			store			: store,
			value			: (record.get('milestone_id') == 0) ? null : record
					.get('milestone_id'),
			width			: 110,
			listeners		: {
				scope		: this,
				'blur'		: function() {
					sibling.remove();
					el.show();
				},
				'select'	: function(field, r) {
					// if the user selected none, do nothing
					if (record.get('milestone_id') == r.get('id'))
						return;

					record.set('milestone_id', (r.get('id')) ? r.get('id') : 0);

					this.showUpdating();

					record.save({
								url		: '/memberships/'
										+ Kohive.OS.getCurrentHive().get('id')
										+ '/tasks/' + record.get('id'),
								scope	: this,
								success	: function(model, response) {
									var task = Ext
											.decode(response.responseText);
									record.set('milestone_id',
											task.milestone_id
									);
									record.set('milestone', task.milestone);
									record.set('title', "");
									record.set('title', task.title);

									sibling.remove();
									el.show();

									this.hideLoading();
								},
								failure	: function() {
									this.showFailure();
								}
							});
				}
			}
		}
		);

		var tempTask = new Ext.util.DelayedTask(function() {
					field.focus();
					field.el.unselectable();
				}, this);
		tempTask.delay(100);
	},

	showUpdating	: function() {
		var controller = Kohive.OS.getController('tasks');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.showUpdating();
	},

	refreshView		: function() {
		var controller = Kohive.OS.getController('tasks');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.store.load();
	},

	/**
	 * Creates a datepicker for the due date editable field
	 */
	duePicker		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-due-field',
					cls	: 'edit-due-field'
				});

		el.enableDisplayMode();
		el.hide();

		var dateField = new Ext.form.DateField({
					renderTo				: 'edit-due-field',
					name					: 'due',
					value					: (record.get('due_normal'))
							? record.get('due_normal')
							: '',
					showToday				: false,
					width					: 110,
					dontAddClickListener	: true,
					format					: 'd-m-Y', // TODO change to j-M-y when chronic can support it
					minValue				: new Date().format(Kohive.OS
							.getDefaultDateFormat()),
					listeners				: {
						scope			: this,
						'focus'			: function(field) {
							field.onTriggerClick();
						},
						'specialkey'	: function(field) {
							var key = Ext.EventObject.getKey();
							if (key === 13)
								this.saveDueDate(field, record, sibling, el);
						},
						'blur'			: function(field) {
							this.saveDueDate(field, record, sibling, el);
						}
					}
				});

		var tempTask = new Ext.util.DelayedTask(function() {
					dateField.focus();
				}, this);
		tempTask.delay(100);
	},

	saveDueDate		: function(field, record, sibling, el, dataview) {
		var dateOrg = (field.getValue()) ? field.getValue() : field
				.getRawValue();
		date = (dateOrg.format) ? dateOrg.format(Kohive.OS
				.getDefaultDateFormat()) : dateOrg;

		if (date) {
			record.set('due', date);
			record.set('due_date', date);
			record.set('overdue', (function() {
						if (!dateOrg.format)
							return;

						// Convert the due date into a proper JS date, and get the current date
						var dueDate = date;
						var currentDate = new Date();

						// Check if the due date is below or lower than the current date
						if (dueDate < currentDate)
							return true;

						return false;
					})());
		} else {
			record.set('due', '');
			record.set('due_date', '');
			record.set('overdue', false);
		};

		record.save({
					url		: '/memberships/'
							+ Kohive.OS.getCurrentHive().get('id') + '/tasks/'
							+ record.get('id'),
					scope	: this,
					success	: function() {
						sibling.remove();
						el.show();
						this.hideLoading();
					},
					failure	: Ext.emptyFn
				});
	},

	/**
	 * 
	 */
	editTags		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-tags-field'
				});

		el.enableDisplayMode();
		el.hide();

		this.tagsField = new Ext.ux.form.SuperBoxSelect({
					renderTo		: 'edit-tags-field',
					allowAddNewData	: true,
					name			: 'tag_list',
					mode			: 'local',
					store			: indexWindow.tagsStore,
					displayField	: 'tag',
					valueField		: 'tag',
					listeners		: {
						scope		: this,
						newitem		: function(bs, v) {
							var newObj = {
								id		: v,
								name	: v,
								tag		: v
							};
							bs.addItem(newObj);
						},
						expand		: function() {
							var list = this.tagsField.list;

							var tempTask = new Ext.util.DelayedTask(function() {
										list.setTop(list.getTop() + 3);
									}, this);
							tempTask.delay(200);
						},
						'enter-key'	: function(field) {
							this.saveTags(field, record, sibling, el);
						},
						blur		: function(field) {
							this.saveTags(field, record, sibling, el);
						}
					}
				});

		this.tagsField.setWidth(sibling.getWidth());

		// format tags
		var tags = Ext.util.Format.trim(record.get('tag_list')).split(' ');

		var array = [];
		Ext.each(tags, function(t) {
					array.push({
								tag	: t
							});
				}, this);

		// set the tags value
		this.tagsField.setValueEx(array);

		this.tagsField.focus();
	},

	saveTags		: function(field, record, sibling, el, dataview) {
		var val = Ext.util.Format.trim(this.tagsField.getValue()).split(',');

		if (val.length > 0) {
			if (val.length == 1 && val[0] == "") {
				record.set('tag_list', '');
				record.set('tags', false);
				this.tagsField.setValue('');
			} else {
				var newArray = [];

				Ext.each(val, function(a) {
							newArray.push({
										name	: a
									});
						}, this);

				record.set('tag_list', val.join(' '));
				record.set('tags', false);
				record.set('tags', newArray);
				this.tagsField.setValue(val);
			};
		};

		this.showUpdating();

		record.save({
					url		: '/memberships/'
							+ Kohive.OS.getCurrentHive().get('id') + '/tasks/'
							+ record.get('id'),
					scope	: this,
					success	: function() {
						this.tagsField.destroy();
						el.show();
						this.hideLoading();
					},
					failure	: Ext.emptyFn
				});
	}
}
);

/**
 * @class Kohive.models.Video
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.Video", {
	fields			: [{
				name	: 'id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'video_album_id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'author_membership_id',
				type	: 'int',
				virtual	: true
			}, {
				name	: 'reference_id',
				type	: 'string'
			}, {
				name	: 'site',
				type	: 'string'
			}, {
				name	: 'guid',
				type	: 'string'
			}, {
				name	: 'import_string',
				type	: 'string'
			}, {
				name	: 'title',
				type	: 'string'
			}, {
				name	: 'description',
				type	: 'string'
			}, {
				name	: 'created_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'updated_at',
				type	: 'string',
				virtual	: true
			}, {
				name	: 'embed_code',
				type	: 'string',
				virtual	: true
			},

			{
				name	: 'author_nickname',
				type	: 'string',
				virtual	: true,
				convert	: function(value, record) {
					var id = Kohive.OS.getCurrentHive().get('id');

					if (!id || !record.author_membership_id)
						return value;
					if (id == record.author_membership_id)
						return Ext.ux.Translator.translate('me');
					return value;
				}
			},

			{
				name	: 'thumbnail_filename',
				virtual	: true,
				convert	: function(value, record) {
					return 'http://img.youtube.com/vi/' + record.reference_id
							+ '/default.jpg';
				}
			},

			{
				name	: 'tag_list',
				convert	: function(value, record) {
					if (!value && record.tags.length > 0) {
						var res = "";
						Ext.each(record.tags, function(tag) {
									res += tag.name + " ";
								}, this);
						return res;
					} else {
						return value;
					}
				}
			}, {
				name	: 'tags',
				virtual	: true,
				convert	: function(value, record) {
					if (value.length < 1)
						value = false;

					return value;
				}
			},

			{
				name	: 'created_at_date',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS.convertToDate(record.created_at, true);
				}
			}, {
				name	: 'id_card',
				virtual	: true,
				convert	: function(value, record) {
					return Kohive.OS
							.getIdCardFromMembershipId(record.author_membership_id);
				}
			},

			// editable properties
			{
				name	: 'can_edit',
				virtual	: true,
				convert	: function(value, record) {
					// return true always until proper checking can be done
					return true;

					// author
					// mod/owner
					if (Kohive.OS.isAuthor(record))
						return true;
					return false;
				}
			}, {
				name	: 'can_delete',
				virtual	: true,
				convert	: function(value, record) {
					// author
					// recipient
					// mod/owner
					if (Kohive.OS.isAuthor(record) || Kohive.OS.isHiveMod())
						return true;
					return false;
				}
			}],

	belongsTo		: "VideoAlbum",
	hasMany			: "Comment",

	/**
	 * 
	 */
	editTags		: function(dataview, record, el, a, index, indexWindow) {
		var sibling = el.insertSibling({
					id	: 'edit-tags-field'
				});

		el.enableDisplayMode();
		el.hide();

		this.tagsField = new Ext.ux.form.SuperBoxSelect({
					renderTo		: 'edit-tags-field',
					allowAddNewData	: true,
					name			: 'tag_list',
					mode			: 'local',
					store			: indexWindow.tagsStore,
					displayField	: 'tag',
					valueField		: 'tag',
					listeners		: {
						scope		: this,
						newitem		: function(bs, v) {
							var newObj = {
								id		: v,
								name	: v,
								tag		: v
							};
							bs.addItem(newObj);
						},
						expand		: function() {
							var list = this.tagsField.list;

							var tempTask = new Ext.util.DelayedTask(function() {
										list.setTop(list.getTop() + 3);
									}, this);
							tempTask.delay(200);
						},
						'enter-key'	: function(field) {
							this.saveTags(field, record, sibling, el);
						},
						blur		: function(field) {
							this.saveTags(field, record, sibling, el);
						}
					}
				});

		this.tagsField.setWidth(sibling.getWidth());

		// format tags
		var tags = Ext.util.Format.trim(record.get('tag_list')).split(' ');

		var array = [];
		Ext.each(tags, function(t) {
					array.push({
								tag	: t
							});
				}, this);

		// set the tags value
		this.tagsField.setValueEx(array);

		this.tagsField.focus();
	},

	saveTags		: function(field, record, sibling, el, dataview) {
		var val = Ext.util.Format.trim(this.tagsField.getValue()).split(',');

		if (val.length > 0) {
			if (val.length == 1 && val[0] == "") {
				record.set('tag_list', '');
				record.set('tags', false);
				this.tagsField.setValue('');
			} else {
				var newArray = [];

				Ext.each(val, function(a) {
							newArray.push({
										name	: a
									});
						}, this);

				record.set('tag_list', val.join(' '));
				record.set('tags', false);
				record.set('tags', newArray);
				this.tagsField.setValue(val);
			};
		};

		this.showUpdating();

		record.save({
					url		: Kohive.OS.scopedUrl(String.format(
							"video_albums/{0}/videos/{1}", record
									.get('video_album_id'), record.get('id')
					)),
					scope	: this,
					success	: function() {
						sibling.remove();
						el.show();
						this.hideLoading();
					},
					failure	: Ext.emptyFn
				});
	},

	showUpdating	: function() {
		var controller = Kohive.OS.getController('videos');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.showUpdating();
	},

	/**
	 * Hides the loading animation from the view
	 */
	hideLoading		: function() {
		var controller = Kohive.OS.getController('videos');
		var view = controller.indexWindow || null;

		if (view) {
			view.hideLoading();
			view.fireEvent('update-filter-bar', view.cachedStore);
		};
	},

	/**
	 * Refreshes the content in the view
	 */
	refreshView		: function() {
		var controller = Kohive.OS.getController('videos');
		var view = controller.indexWindow || null;

		if (view && view.store)
			view.store.load();
		if (view)
			view.hideLoading();
	}
}
);

/**
 * @class Kohive.models.VideoAlbum
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.VideoAlbum", {
			modelName	: 'video_album',
			jsonName	: 'video_album',
			urlName		: 'video_album',

			fields		: [{
						name	: 'id',
						type	: 'int'
					}, {
						name	: 'author_membership_id',
						type	: 'int'
					}, {
						name	: 'title',
						type	: 'string'
					}, {
						name	: 'hive_id',
						type	: 'int'
					}, {
						name	: 'type',
						type	: 'string'
					}, {
						name	: 'feed_url',
						type	: 'string'
					}, {
						name	: 'created_at',
						type	: 'string'
					}, {
						name	: 'updated_at',
						type	: 'string'
					},

					// editable properties
					{
						name	: 'can_edit',
						virtual	: true,
						convert	: function(value, record) {
							// return true always until proper checking can be done
							return true;

							// author
							// mod/owner
							if (Kohive.OS.isAuthor(record))
								return true;
							return false;
						}
					}, {
						name	: 'can_delete',
						virtual	: true,
						convert	: function(value, record) {
							// author
							// recipient
							// mod/owner
							if (Kohive.OS.isAuthor(record)
									|| Kohive.OS.isHiveMod())
								return true;
							return false;
						}
					}],
			hasMany		: "Video"
		});

/**
 * @class Kohive.models.UrlInfo
 * @extends ExtMVC.Model
 */
ExtMVC.Model.define("Kohive.models.UrlInfo", {
			fields	: [{
						name	: 'address'
					}]
		});